From ced9d38abc55236c9be86f61fa86c3f79916849b Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Wed, 29 Jan 2025 02:44:32 +0530 Subject: [PATCH] feat: async parser workers (#3834) --- .../CollectionSettings/Docs/index.js | 28 +++-- .../CollectionSettings/Info/StyledWrapper.js | 13 -- .../{ => Overview}/Info/index.js | 19 ++- .../RequestsNotLoaded/StyledWrapper.js | 25 ++++ .../Overview/RequestsNotLoaded/index.js | 50 ++++++++ .../CollectionSettings/Overview/index.js | 61 ++------- .../components/CollectionSettings/index.js | 15 --- .../src/components/MarkDown/StyledWrapper.js | 7 -- .../RequestIsLoading/StyledWrapper.js | 19 +++ .../RequestTabPanel/RequestIsLoading/index.js | 58 ++++++--- .../RequestNotLoaded/StyledWrapper.js | 19 +++ .../RequestTabPanel/RequestNotLoaded/index.js | 116 +++++++++++------- .../RequestTabPanel/StyledWrapper.js | 4 - .../src/components/RunnerResults/index.jsx | 2 +- .../CollectionItem/RunCollectionItem/index.js | 4 +- .../Sidebar/Collections/Collection/index.js | 5 +- .../ReduxStore/slices/collections/actions.js | 14 +-- packages/bruno-app/src/themes/dark.js | 20 ++- packages/bruno-app/src/themes/light.js | 17 ++- .../bruno-electron/src/app/collections.js | 7 +- packages/bruno-electron/src/app/watcher.js | 12 +- packages/bruno-electron/src/ipc/collection.js | 44 ++++--- .../bruno-electron/src/utils/collection.js | 4 +- .../bruno-electron/src/utils/filesystem.js | 10 +- .../tests/utils/collection.spec.js | 22 ++-- 25 files changed, 365 insertions(+), 230 deletions(-) delete mode 100644 packages/bruno-app/src/components/CollectionSettings/Info/StyledWrapper.js rename packages/bruno-app/src/components/CollectionSettings/{ => Overview}/Info/index.js (70%) create mode 100644 packages/bruno-app/src/components/CollectionSettings/Overview/RequestsNotLoaded/StyledWrapper.js create mode 100644 packages/bruno-app/src/components/CollectionSettings/Overview/RequestsNotLoaded/index.js create mode 100644 packages/bruno-app/src/components/RequestTabPanel/RequestIsLoading/StyledWrapper.js create mode 100644 packages/bruno-app/src/components/RequestTabPanel/RequestNotLoaded/StyledWrapper.js diff --git a/packages/bruno-app/src/components/CollectionSettings/Docs/index.js b/packages/bruno-app/src/components/CollectionSettings/Docs/index.js index e96b1c6e4..2d869de65 100644 --- a/packages/bruno-app/src/components/CollectionSettings/Docs/index.js +++ b/packages/bruno-app/src/components/CollectionSettings/Docs/index.js @@ -8,7 +8,7 @@ import { saveCollectionRoot } from 'providers/ReduxStore/slices/collections/acti import Markdown from 'components/MarkDown'; import CodeEditor from 'components/CodeEditor'; import StyledWrapper from './StyledWrapper'; -import { IconEdit, IconTrash, IconFileText } from '@tabler/icons'; +import { IconEdit, IconX, IconFileText } from '@tabler/icons'; const Docs = ({ collection }) => { const dispatch = useDispatch(); @@ -42,6 +42,7 @@ const Docs = ({ collection }) => { const onSave = () => { dispatch(saveCollectionRoot(collection.uid)); + toggleViewMode(); } return ( @@ -52,15 +53,20 @@ const Docs = ({ collection }) => { Documentation
-
- {isEditing ? : } -
- {/*
- -
*/} - {/* */} + {isEditing ? ( + <> +
+ +
+ + + ) : ( +
+ +
+ )}
{isEditing ? ( @@ -75,7 +81,7 @@ const Docs = ({ collection }) => { fontSize={get(preferences, 'font.codeFontSize')} /> ) : ( -
+
{ docs?.length > 0 ? diff --git a/packages/bruno-app/src/components/CollectionSettings/Info/StyledWrapper.js b/packages/bruno-app/src/components/CollectionSettings/Info/StyledWrapper.js deleted file mode 100644 index 7fd98347c..000000000 --- a/packages/bruno-app/src/components/CollectionSettings/Info/StyledWrapper.js +++ /dev/null @@ -1,13 +0,0 @@ -import styled from 'styled-components'; - -const StyledWrapper = styled.div` - table { - td { - &:first-child { - width: 120px; - } - } - } -`; - -export default StyledWrapper; diff --git a/packages/bruno-app/src/components/CollectionSettings/Info/index.js b/packages/bruno-app/src/components/CollectionSettings/Overview/Info/index.js similarity index 70% rename from packages/bruno-app/src/components/CollectionSettings/Info/index.js rename to packages/bruno-app/src/components/CollectionSettings/Overview/Info/index.js index 6cacbfead..86bf2308f 100644 --- a/packages/bruno-app/src/components/CollectionSettings/Info/index.js +++ b/packages/bruno-app/src/components/CollectionSettings/Overview/Info/index.js @@ -1,5 +1,4 @@ import React from 'react'; -import StyledWrapper from './StyledWrapper'; import { getTotalRequestCountInCollection } from 'utils/collections/'; import { IconFolder, IconFileOff, IconWorld, IconApi } from '@tabler/icons'; @@ -7,8 +6,8 @@ const Info = ({ collection }) => { const totalRequestsInCollection = getTotalRequestCountInCollection(collection); return ( - -
+
+
{/* Location Row */}
@@ -16,8 +15,8 @@ const Info = ({ collection }) => {
-
Location
-
+
Location
+
{collection.pathname}
@@ -29,8 +28,8 @@ const Info = ({ collection }) => {
-
Environments
-
+
Environments
+
{collection.environments?.length || 0} environment{collection.environments?.length !== 1 ? 's' : ''} configured
@@ -42,15 +41,15 @@ const Info = ({ collection }) => {
-
Requests
-
+
Requests
+
{totalRequestsInCollection} request{totalRequestsInCollection !== 1 ? 's' : ''} in collection
- +
); }; diff --git a/packages/bruno-app/src/components/CollectionSettings/Overview/RequestsNotLoaded/StyledWrapper.js b/packages/bruno-app/src/components/CollectionSettings/Overview/RequestsNotLoaded/StyledWrapper.js new file mode 100644 index 000000000..e9a9cd06f --- /dev/null +++ b/packages/bruno-app/src/components/CollectionSettings/Overview/RequestsNotLoaded/StyledWrapper.js @@ -0,0 +1,25 @@ +import styled from 'styled-components'; + +const StyledWrapper = styled.div` + &.card { + background-color: ${(props) => props.theme.requestTabPanel.card.bg}; + + .title { + border-top: 1px solid ${(props) => props.theme.requestTabPanel.cardTable.border}; + border-left: 1px solid ${(props) => props.theme.requestTabPanel.cardTable.border}; + border-right: 1px solid ${(props) => props.theme.requestTabPanel.cardTable.border}; + + border-top-left-radius: 3px; + border-top-right-radius: 3px; + } + + .table { + thead { + background-color: ${(props) => props.theme.requestTabPanel.cardTable.table.thead.bg}; + color: ${(props) => props.theme.requestTabPanel.cardTable.table.thead.color}; + } + } + } +`; + +export default StyledWrapper; diff --git a/packages/bruno-app/src/components/CollectionSettings/Overview/RequestsNotLoaded/index.js b/packages/bruno-app/src/components/CollectionSettings/Overview/RequestsNotLoaded/index.js new file mode 100644 index 000000000..c15b36cd8 --- /dev/null +++ b/packages/bruno-app/src/components/CollectionSettings/Overview/RequestsNotLoaded/index.js @@ -0,0 +1,50 @@ +import React from 'react'; +import { flattenItems } from "utils/collections"; +import { IconAlertTriangle } from '@tabler/icons'; +import StyledWrapper from "./StyledWrapper"; + +const RequestsNotLoaded = ({ collection }) => { + const flattenedItems = flattenItems(collection.items); + const itemsFailedLoading = flattenedItems?.filter(item => item?.partial && !item?.loading); + + if (!itemsFailedLoading?.length) { + return null; + } + + return ( + +
+ + Following requests were not loaded +
+ + + + + + + + + {flattenedItems?.map((item, index) => ( + item?.partial && !item?.loading ? ( + + + + + ) : null + ))} + +
+ Pathname + + Size +
+ {item?.pathname?.split(`${collection?.pathname}/`)?.[1]} + + {item?.size?.toFixed?.(2)} MB +
+
+ ); +}; + +export default RequestsNotLoaded; diff --git a/packages/bruno-app/src/components/CollectionSettings/Overview/index.js b/packages/bruno-app/src/components/CollectionSettings/Overview/index.js index b67d75c16..87b461e9c 100644 --- a/packages/bruno-app/src/components/CollectionSettings/Overview/index.js +++ b/packages/bruno-app/src/components/CollectionSettings/Overview/index.js @@ -1,67 +1,26 @@ -import { flattenItems } from "utils/collections/index"; import StyledWrapper from "./StyledWrapper"; -import Docs from "../Docs/index"; -import Info from "../Info/index"; -import { IconBox, IconAlertTriangle } from '@tabler/icons'; +import Docs from "../Docs"; +import Info from "./Info"; +import { IconBox } from '@tabler/icons'; +import RequestsNotLoaded from "./RequestsNotLoaded"; const Overview = ({ collection }) => { - const flattenedItems = flattenItems(collection.items); - const itemsFailedLoading = flattenedItems?.filter(item => item?.partial && !item?.loading); return ( - -
-
+
+
+
- + {collection?.name}
- { - itemsFailedLoading?.length ? -
-
- Following requests were not loaded -
- - - - - - - - - {flattenedItems?.map(item => ( - <> - { - item?.partial && !item?.loading ? - - - - - : null - } - - ))} - -
-
- Pathname -
-
-
- Size -
-
{item?.pathname?.split(`${collection?.pathname}/`)?.[1]}{item?.size?.toFixed?.(2)} MB
-
- : - null - } +
- +
); } diff --git a/packages/bruno-app/src/components/CollectionSettings/index.js b/packages/bruno-app/src/components/CollectionSettings/index.js index 25c5dba1f..7d5d60574 100644 --- a/packages/bruno-app/src/components/CollectionSettings/index.js +++ b/packages/bruno-app/src/components/CollectionSettings/index.js @@ -12,9 +12,7 @@ import Headers from './Headers'; import Auth from './Auth'; import Script from './Script'; import Test from './Tests'; -import Docs from './Docs'; import Presets from './Presets'; -import Info from './Info'; import StyledWrapper from './StyledWrapper'; import Vars from './Vars/index'; import DotIcon from 'components/Icons/Dot'; @@ -132,12 +130,6 @@ const CollectionSettings = ({ collection }) => { /> ); } - case 'docs': { - return ; - } - case 'info': { - return ; - } } }; @@ -184,13 +176,6 @@ const CollectionSettings = ({ collection }) => { Client Certificates {clientCertConfig.length > 0 && }
- {/*
setTab('docs')}> - Docs - {hasDocs && } -
-
setTab('info')}> - Info -
*/}
{getTabPanel(tab)}
diff --git a/packages/bruno-app/src/components/MarkDown/StyledWrapper.js b/packages/bruno-app/src/components/MarkDown/StyledWrapper.js index fa1269e14..0ac61b4e5 100644 --- a/packages/bruno-app/src/components/MarkDown/StyledWrapper.js +++ b/packages/bruno-app/src/components/MarkDown/StyledWrapper.js @@ -9,7 +9,6 @@ const StyledMarkdownBodyWrapper = styled.div` box-sizing: border-box; height: 100%; margin: 0 auto; - padding-top: 0.5rem; font-size: 0.875rem; h1 { @@ -80,12 +79,6 @@ const StyledMarkdownBodyWrapper = styled.div` } } } - - @media (max-width: 767px) { - .markdown-body { - padding: 15px; - } - } `; export default StyledMarkdownBodyWrapper; diff --git a/packages/bruno-app/src/components/RequestTabPanel/RequestIsLoading/StyledWrapper.js b/packages/bruno-app/src/components/RequestTabPanel/RequestIsLoading/StyledWrapper.js new file mode 100644 index 000000000..ff6c48575 --- /dev/null +++ b/packages/bruno-app/src/components/RequestTabPanel/RequestIsLoading/StyledWrapper.js @@ -0,0 +1,19 @@ +import styled from 'styled-components'; + +const StyledWrapper = styled.div` + div.card { + background: ${(props) => props.theme.requestTabPanel.card.bg}; + border: 1px solid ${(props) => props.theme.requestTabPanel.card.border}; + + div.hr { + border-bottom: 1px solid ${(props) => props.theme.requestTabPanel.card.hr}; + height: 1px; + } + + div.border-top { + border-top: 1px solid ${(props) => props.theme.requestTabPanel.card.border}; + } + } +`; + +export default StyledWrapper; diff --git a/packages/bruno-app/src/components/RequestTabPanel/RequestIsLoading/index.js b/packages/bruno-app/src/components/RequestTabPanel/RequestIsLoading/index.js index e2d65d123..9d2ff1346 100644 --- a/packages/bruno-app/src/components/RequestTabPanel/RequestIsLoading/index.js +++ b/packages/bruno-app/src/components/RequestTabPanel/RequestIsLoading/index.js @@ -1,27 +1,47 @@ -import { IconLoader2 } from '@tabler/icons'; +import { IconLoader2, IconFile } from '@tabler/icons'; +import StyledWrapper from './StyledWrapper'; const RequestIsLoading = ({ item }) => { - return <> -
-
-
-
Name
-
{item?.name}
-
-
-
Size
-
{item?.size?.toFixed?.(2)} MB
-
-
-
Path
-
{item?.pathname}
-
-
- + return +
+
+
+
+ + File Info +
+
+ +
+ Name: +
+ {item?.name} +
+
+ +
+ Path: +
+ {item?.pathname} +
+
+ +
+ Size: +
+ {item?.size?.toFixed?.(2)} MB +
+
+ +
+
+ + Loading... +
- + } export default RequestIsLoading; \ No newline at end of file diff --git a/packages/bruno-app/src/components/RequestTabPanel/RequestNotLoaded/StyledWrapper.js b/packages/bruno-app/src/components/RequestTabPanel/RequestNotLoaded/StyledWrapper.js new file mode 100644 index 000000000..ff6c48575 --- /dev/null +++ b/packages/bruno-app/src/components/RequestTabPanel/RequestNotLoaded/StyledWrapper.js @@ -0,0 +1,19 @@ +import styled from 'styled-components'; + +const StyledWrapper = styled.div` + div.card { + background: ${(props) => props.theme.requestTabPanel.card.bg}; + border: 1px solid ${(props) => props.theme.requestTabPanel.card.border}; + + div.hr { + border-bottom: 1px solid ${(props) => props.theme.requestTabPanel.card.hr}; + height: 1px; + } + + div.border-top { + border-top: 1px solid ${(props) => props.theme.requestTabPanel.card.border}; + } + } +`; + +export default StyledWrapper; diff --git a/packages/bruno-app/src/components/RequestTabPanel/RequestNotLoaded/index.js b/packages/bruno-app/src/components/RequestTabPanel/RequestNotLoaded/index.js index 95c2e8c00..1a951b624 100644 --- a/packages/bruno-app/src/components/RequestTabPanel/RequestNotLoaded/index.js +++ b/packages/bruno-app/src/components/RequestTabPanel/RequestNotLoaded/index.js @@ -1,57 +1,89 @@ -import { IconLoader2 } from '@tabler/icons'; -import { loadRequest, loadRequestSync } from 'providers/ReduxStore/slices/collections/actions'; +import { IconLoader2, IconFile } from '@tabler/icons'; +import { loadRequest, loadRequestViaWorker } from 'providers/ReduxStore/slices/collections/actions'; import { useDispatch } from 'react-redux'; +import StyledWrapper from './StyledWrapper'; const RequestNotLoaded = ({ collection, item }) => { const dispatch = useDispatch(); + const handleLoadRequestViaWorker = () => { + !item?.loading && dispatch(loadRequestViaWorker({ collectionUid: collection?.uid, pathname: item?.pathname })); + } + const handleLoadRequest = () => { !item?.loading && dispatch(loadRequest({ collectionUid: collection?.uid, pathname: item?.pathname })); } - const handleLoadRequestSync = () => { - !item?.loading && dispatch(loadRequestSync({ collectionUid: collection?.uid, pathname: item?.pathname })); - } + return +
+
+
+
+ + File Info +
+
- return <> -
-
-
-
Name
-
{item?.name}
-
-
-
Size
-
{item?.size?.toFixed?.(2)} MB
-
-
-
Path
-
{item?.pathname}
+
+ Name: +
{item?.name}
+
+ +
+ Path: +
{item?.pathname}
+
+ +
+ Size: +
{item?.size?.toFixed?.(2)} MB
+
+ + {!item?.error && ( + <> +
+
+ Due to its large size, this request wasn't loaded automatically. +
+
+
+ + + May cause the app to freeze temporarily while it runs. + +
+
+ + + Runs in background. + +
+
+ + )} + + {item?.loading && ( + <> +
+
+ + Loading... +
+ + )}
- {!item?.error ? -
-
- - - May cause the app to freeze temporarily while it runs. - -
-
- - - Runs in background. - -
-
- : null}
- + } export default RequestNotLoaded; \ No newline at end of file diff --git a/packages/bruno-app/src/components/RequestTabPanel/StyledWrapper.js b/packages/bruno-app/src/components/RequestTabPanel/StyledWrapper.js index 112c3ff79..ec0a03217 100644 --- a/packages/bruno-app/src/components/RequestTabPanel/StyledWrapper.js +++ b/packages/bruno-app/src/components/RequestTabPanel/StyledWrapper.js @@ -45,10 +45,6 @@ const StyledWrapper = styled.div` display: flex; } } - - .partial-request-overlay { - background: ${(props) => props.theme.bg}; - } `; export default StyledWrapper; diff --git a/packages/bruno-app/src/components/RunnerResults/index.jsx b/packages/bruno-app/src/components/RunnerResults/index.jsx index dc6ad94e8..4381c86b1 100644 --- a/packages/bruno-app/src/components/RunnerResults/index.jsx +++ b/packages/bruno-app/src/components/RunnerResults/index.jsx @@ -9,7 +9,7 @@ import { IconRefresh, IconCircleCheck, IconCircleX, IconCheck, IconX, IconRun } import slash from 'utils/common/slash'; import ResponsePane from './ResponsePane'; import StyledWrapper from './StyledWrapper'; -import { areItemsLoading } from 'utils/collections/index'; +import { areItemsLoading } from 'utils/collections'; const getRelativePath = (fullPath, pathname) => { // convert to unix style path diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RunCollectionItem/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RunCollectionItem/index.js index e4642801e..cfd236f8c 100644 --- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RunCollectionItem/index.js +++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RunCollectionItem/index.js @@ -7,7 +7,7 @@ import { addTab } from 'providers/ReduxStore/slices/tabs'; import { runCollectionFolder } from 'providers/ReduxStore/slices/collections/actions'; import { flattenItems } from 'utils/collections'; import StyledWrapper from './StyledWrapper'; -import { areItemsLoading } from 'utils/collections/index'; +import { areItemsLoading } from 'utils/collections'; const RunCollectionItem = ({ collection, item, onClose }) => { const dispatch = useDispatch(); @@ -34,6 +34,8 @@ const RunCollectionItem = ({ collection, item, onClose }) => { const recursiveRunLength = getRequestsCount(flattenedItems); const isFolderLoading = areItemsLoading(item); + console.log(item); + console.log(isFolderLoading); return ( diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/index.js index 326af077a..1b16f4eea 100644 --- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/index.js +++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/index.js @@ -19,8 +19,8 @@ import { isItemAFolder, isItemARequest } from 'utils/collections'; import RenameCollection from './RenameCollection'; import StyledWrapper from './StyledWrapper'; -import CloneCollection from './CloneCollection/index'; -import { areItemsLoading } from 'utils/collections/index'; +import CloneCollection from './CloneCollection'; +import { areItemsLoading } from 'utils/collections'; const Collection = ({ collection, searchText }) => { const [showNewFolderModal, setShowNewFolderModal] = useState(false); @@ -63,7 +63,6 @@ const Collection = ({ collection, searchText }) => { // Check if the click came from the chevron icon const isChevronClick = event.target.closest('svg')?.classList.contains('chevron-icon'); - console.log('handleClick', collection.mountStatus); if (collection.mountStatus === 'unmounted') { dispatch(mountCollection({ collectionUid: collection.uid, diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js index 9c11a256c..4a0b5bf1f 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js @@ -1193,6 +1193,13 @@ export const hydrateCollectionWithUiStateSnapshot = (payload) => (dispatch, getS }); }; +export const loadRequestViaWorker = ({ collectionUid, pathname }) => (dispatch, getState) => { + return new Promise(async (resolve, reject) => { + const { ipcRenderer } = window; + ipcRenderer.invoke('renderer:load-request-via-worker', { collectionUid, pathname }).then(resolve).catch(reject); + }); +}; + export const loadRequest = ({ collectionUid, pathname }) => (dispatch, getState) => { return new Promise(async (resolve, reject) => { const { ipcRenderer } = window; @@ -1200,13 +1207,6 @@ export const loadRequest = ({ collectionUid, pathname }) => (dispatch, getState) }); }; -export const loadRequestSync = ({ collectionUid, pathname }) => (dispatch, getState) => { - return new Promise(async (resolve, reject) => { - const { ipcRenderer } = window; - ipcRenderer.invoke('renderer:load-request-sync', { collectionUid, pathname }).then(resolve).catch(reject); - }); -}; - export const mountCollection = ({ collectionUid, collectionPathname, brunoConfig }) => (dispatch, getState) => { dispatch(updateCollectionMountStatus({ collectionUid, mountStatus: 'mounting' })); return new Promise(async (resolve, reject) => { diff --git a/packages/bruno-app/src/themes/dark.js b/packages/bruno-app/src/themes/dark.js index 9e8e923aa..a47abb8d2 100644 --- a/packages/bruno-app/src/themes/dark.js +++ b/packages/bruno-app/src/themes/dark.js @@ -114,7 +114,25 @@ const darkTheme = { responseStatus: '#ccc', responseOk: '#8cd656', responseError: '#f06f57', - responseOverlayBg: 'rgba(30, 30, 30, 0.6)' + responseOverlayBg: 'rgba(30, 30, 30, 0.6)', + + card: { + bg: '#252526', + border: 'transparent', + borderDark: '#8cd656', + hr: '#424242' + }, + + cardTable: { + border: '#333', + bg: '#252526', + table: { + thead: { + bg: '#3D3D3D', + color: '#ccc' + } + } + } }, collection: { diff --git a/packages/bruno-app/src/themes/light.js b/packages/bruno-app/src/themes/light.js index a25583136..9d3439895 100644 --- a/packages/bruno-app/src/themes/light.js +++ b/packages/bruno-app/src/themes/light.js @@ -114,7 +114,22 @@ const lightTheme = { responseStatus: 'rgb(117 117 117)', responseOk: '#047857', responseError: 'rgb(185, 28, 28)', - responseOverlayBg: 'rgba(255, 255, 255, 0.6)' + responseOverlayBg: 'rgba(255, 255, 255, 0.6)', + card: { + bg: '#fff', + border: '#f4f4f4', + hr: '#f4f4f4' + }, + cardTable: { + border: '#efefef', + bg: '#fff', + table: { + thead: { + bg: 'rgb(249, 250, 251)', + color: 'rgb(75 85 99)' + } + } + } }, collection: { diff --git a/packages/bruno-electron/src/app/collections.js b/packages/bruno-electron/src/app/collections.js index 2b94e1c7f..7bd74c43b 100644 --- a/packages/bruno-electron/src/app/collections.js +++ b/packages/bruno-electron/src/app/collections.js @@ -2,7 +2,7 @@ const fs = require('fs'); const path = require('path'); const { dialog, ipcMain } = require('electron'); const Yup = require('yup'); -const { isDirectory, normalizeAndResolvePath, addCollectionStatsToBrunoConfig } = require('../utils/filesystem'); +const { isDirectory, normalizeAndResolvePath, getCollectionStats } = require('../utils/filesystem'); const { generateUidBasedOnHash } = require('../utils/common'); // todo: bruno.json config schema validation errors must be propagated to the UI @@ -69,7 +69,10 @@ const openCollection = async (win, watcher, collectionPath, options = {}) => { // this is to maintain backwards compatibility with older collections brunoConfig.ignore = ['node_modules', '.git']; } - brunoConfig = await addCollectionStatsToBrunoConfig({ brunoConfig, collectionPath }); + + const { size, filesCount } = await getCollectionStats(collectionPath); + brunoConfig.size = size; + brunoConfig.filesCount = filesCount; win.webContents.send('main:collection-opened', collectionPath, uid, brunoConfig); ipcMain.emit('main:collection-opened', win, collectionPath, uid, brunoConfig); diff --git a/packages/bruno-electron/src/app/watcher.js b/packages/bruno-electron/src/app/watcher.js index 90ead1705..b2b60fd55 100644 --- a/packages/bruno-electron/src/app/watcher.js +++ b/packages/bruno-electron/src/app/watcher.js @@ -13,7 +13,7 @@ const { setDotEnvVars } = require('../store/process-env'); const { setBrunoConfig } = require('../store/bruno-config'); const EnvironmentSecretsStore = require('../store/env-secrets'); const UiStateSnapshot = require('../store/ui-state-snapshot'); -const { getBruFileMeta, hydrateRequestWithUuid } = require('../utils/collection'); +const { parseBruFileMeta, hydrateRequestWithUuid } = require('../utils/collection'); const MAX_FILE_SIZE = 2.5 * 1024 * 1024; @@ -166,7 +166,7 @@ const add = async (win, pathname, collectionUid, collectionPath, useWorkerThread if (isBrunoConfigFile(pathname, collectionPath)) { try { const content = fs.readFileSync(pathname, 'utf8'); - let brunoConfig = JSON.parse(content); + const brunoConfig = JSON.parse(content); setBrunoConfig(collectionUid, brunoConfig); } catch (err) { @@ -279,21 +279,23 @@ const add = async (win, pathname, collectionUid, collectionPath, useWorkerThread type: 'http-request' }; - const metaJson = await bruToJson(getBruFileMeta(bruContent), true); + const metaJson = await bruToJson(parseBruFileMeta(bruContent), true); file.data = metaJson; file.partial = true; file.loading = false; file.size = sizeInMB(fileStats?.size); hydrateRequestWithUuid(file.data, pathname); win.webContents.send('main:collection-tree-updated', 'addFile', file); - // If the file is smaller than the max file size, we can parse the file - // and send the full file info to the UI + if (fileStats.size < MAX_FILE_SIZE) { + // This is to update the loading indicator in the UI file.data = metaJson; file.partial = false; file.loading = true; hydrateRequestWithUuid(file.data, pathname); win.webContents.send('main:collection-tree-updated', 'addFile', file); + + // This is to update the file info in the UI file.data = await bruToJsonViaWorker(bruContent); file.partial = false; file.loading = false; diff --git a/packages/bruno-electron/src/ipc/collection.js b/packages/bruno-electron/src/ipc/collection.js index 5ce100572..b9061a227 100644 --- a/packages/bruno-electron/src/ipc/collection.js +++ b/packages/bruno-electron/src/ipc/collection.js @@ -25,8 +25,7 @@ const { isValidFilename, hasSubDirectories, getCollectionStats, - sizeInMB, - addCollectionStatsToBrunoConfig + sizeInMB } = require('../utils/filesystem'); const { openCollectionDialog } = require('../app/collections'); const { generateUidBasedOnHash, stringifyJson, safeParseJSON, safeStringifyJSON } = require('../utils/common'); @@ -35,7 +34,7 @@ const { deleteCookiesForDomain, getDomainsWithCookies } = require('../utils/cook const EnvironmentSecretsStore = require('../store/env-secrets'); const CollectionSecurityStore = require('../store/collection-security'); const UiStateSnapshotStore = require('../store/ui-state-snapshot'); -const { getBruFileMeta, hydrateRequestWithUuid } = require('../utils/collection'); +const { parseBruFileMeta, hydrateRequestWithUuid } = require('../utils/collection'); const environmentSecretsStore = new EnvironmentSecretsStore(); const collectionSecurityStore = new CollectionSecurityStore(); @@ -97,7 +96,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection } const uid = generateUidBasedOnHash(dirPath); - let brunoConfig = { + const brunoConfig = { version: '1', name: collectionName, type: 'collection', @@ -106,7 +105,9 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection const content = await stringifyJson(brunoConfig); await writeFile(path.join(dirPath, 'bruno.json'), content); - brunoConfig = await addCollectionStatsToBrunoConfig({ brunoConfig, collectionPath: dirPath }); + const { size, filesCount } = await getCollectionStats(dirPath); + brunoConfig.size = size; + brunoConfig.filesCount = filesCount; mainWindow.webContents.send('main:collection-opened', dirPath, uid, brunoConfig); ipcMain.emit('main:collection-opened', mainWindow, dirPath, uid, brunoConfig); @@ -158,7 +159,9 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection fs.copyFileSync(sourceFilePath, newFilePath); } - brunoConfig = await addCollectionStatsToBrunoConfig({ brunoConfig, collectionPath: dirPath }); + const { size, filesCount } = await getCollectionStats(dirPath); + brunoConfig.size = size; + brunoConfig.filesCount = filesCount; mainWindow.webContents.send('main:collection-opened', dirPath, uid, brunoConfig); ipcMain.emit('main:collection-opened', mainWindow, dirPath, uid); @@ -601,7 +604,9 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection const collectionContent = await jsonToCollectionBru(collection.root); await writeFile(path.join(collectionPath, 'collection.bru'), collectionContent); - brunoConfig = await addCollectionStatsToBrunoConfig({ brunoConfig, collectionPath }); + const { size, filesCount } = await getCollectionStats(collectionPath); + brunoConfig.size = size; + brunoConfig.filesCount = filesCount; mainWindow.webContents.send('main:collection-opened', collectionPath, uid, brunoConfig); ipcMain.emit('main:collection-opened', mainWindow, collectionPath, uid, brunoConfig); @@ -792,7 +797,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection } }); - ipcMain.handle('renderer:load-request', async (event, { collectionUid, pathname }) => { + ipcMain.handle('renderer:load-request-via-worker', async (event, { collectionUid, pathname }) => { let fileStats; try { fileStats = fs.statSync(pathname); @@ -805,7 +810,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection } }; let bruContent = fs.readFileSync(pathname, 'utf8'); - const metaJson = await bruToJson(getBruFileMeta(bruContent), true); + const metaJson = await bruToJson(parseBruFileMeta(bruContent), true); file.data = metaJson; file.loading = true; file.partial = true; @@ -829,7 +834,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection } }; let bruContent = fs.readFileSync(pathname, 'utf8'); - const metaJson = await bruToJson(getBruFileMeta(bruContent), true); + const metaJson = await bruToJson(parseBruFileMeta(bruContent), true); file.data = metaJson; file.partial = true; file.loading = false; @@ -841,7 +846,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection } }); - ipcMain.handle('renderer:load-request-sync', async (event, { collectionUid, pathname }) => { + ipcMain.handle('renderer:load-request', async (event, { collectionUid, pathname }) => { let fileStats; try { fileStats = fs.statSync(pathname); @@ -854,7 +859,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection } }; let bruContent = fs.readFileSync(pathname, 'utf8'); - const metaJson = await bruToJson(getBruFileMeta(bruContent), true); + const metaJson = await bruToJson(parseBruFileMeta(bruContent), true); file.data = metaJson; file.loading = true; file.partial = true; @@ -878,7 +883,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection } }; let bruContent = fs.readFileSync(pathname, 'utf8'); - const metaJson = await bruToJson(getBruFileMeta(bruContent), true); + const metaJson = await bruToJson(parseBruFileMeta(bruContent), true); file.data = metaJson; file.partial = true; file.loading = false; @@ -891,8 +896,17 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection }); ipcMain.handle('renderer:mount-collection', async (event, { collectionUid, collectionPathname, brunoConfig }) => { - const { size: collectionSize, filesCount: collectionBruFilesCount, maxFileSize: maxSingleBruFileSize } = await getCollectionStats(collectionPathname); - const shouldLoadCollectionAsync = (collectionSize > MAX_COLLECTION_SIZE_IN_MB) || (collectionBruFilesCount > MAX_COLLECTION_FILES_COUNT) || (maxSingleBruFileSize > MAX_SINGLE_FILE_SIZE_IN_COLLECTION_IN_MB); + const { + size, + filesCount, + maxFileSize + } = await getCollectionStats(collectionPathname); + + const shouldLoadCollectionAsync = + (size > MAX_COLLECTION_SIZE_IN_MB) || + (filesCount > MAX_COLLECTION_FILES_COUNT) || + (maxFileSize > MAX_SINGLE_FILE_SIZE_IN_COLLECTION_IN_MB); + watcher.addWatcher(mainWindow, collectionPathname, collectionUid, brunoConfig, false, shouldLoadCollectionAsync); }); }; diff --git a/packages/bruno-electron/src/utils/collection.js b/packages/bruno-electron/src/utils/collection.js index 96f3a7b16..d0ec68ab1 100644 --- a/packages/bruno-electron/src/utils/collection.js +++ b/packages/bruno-electron/src/utils/collection.js @@ -207,7 +207,7 @@ const getTreePathFromCollectionToItem = (collection, _item) => { return path; }; -const getBruFileMeta = (data) => { +const parseBruFileMeta = (data) => { try { const metaRegex = /meta\s*{\s*([\s\S]*?)\s*}/; const match = data?.match?.(metaRegex); @@ -282,6 +282,6 @@ module.exports = { findItemByPathname, findItemInCollectionByPathname, findParentItemInCollection, - getBruFileMeta, + parseBruFileMeta, hydrateRequestWithUuid }; \ No newline at end of file diff --git a/packages/bruno-electron/src/utils/filesystem.js b/packages/bruno-electron/src/utils/filesystem.js index 2b928ce34..0ab6bbf0a 100644 --- a/packages/bruno-electron/src/utils/filesystem.js +++ b/packages/bruno-electron/src/utils/filesystem.js @@ -255,13 +255,6 @@ const sizeInMB = (size) => { return size / (1024 * 1024); } -const addCollectionStatsToBrunoConfig = async ({ brunoConfig, collectionPath }) => { - const { size: collectionSize, filesCount: collectionBruFilesCount } = await getCollectionStats(collectionPath); - brunoConfig.size = collectionSize; - brunoConfig.filesCount = collectionBruFilesCount; - return brunoConfig; -} - module.exports = { isValidPathname, exists, @@ -288,6 +281,5 @@ module.exports = { isValidFilename, hasSubDirectories, getCollectionStats, - sizeInMB, - addCollectionStatsToBrunoConfig + sizeInMB }; diff --git a/packages/bruno-electron/tests/utils/collection.spec.js b/packages/bruno-electron/tests/utils/collection.spec.js index 3373696c4..4efc9c002 100644 --- a/packages/bruno-electron/tests/utils/collection.spec.js +++ b/packages/bruno-electron/tests/utils/collection.spec.js @@ -1,6 +1,6 @@ -const { getBruFileMeta } = require("../../src/utils/collection"); +const { parseBruFileMeta } = require("../../src/utils/collection"); -describe('getBruFileMeta', () => { +describe('parseBruFileMeta', () => { test('parses valid meta block correctly', () => { const data = `meta { name: 0.2_mb @@ -8,7 +8,7 @@ describe('getBruFileMeta', () => { seq: 1 }`; - const result = getBruFileMeta(data); + const result = parseBruFileMeta(data); expect(result).toEqual({ meta: { @@ -24,7 +24,7 @@ describe('getBruFileMeta', () => { key: value }`; - const result = getBruFileMeta(data); + const result = parseBruFileMeta(data); expect(result).toBeUndefined(); }); @@ -32,7 +32,7 @@ describe('getBruFileMeta', () => { test('handles empty meta block gracefully', () => { const data = `meta {}`; - const result = getBruFileMeta(data); + const result = parseBruFileMeta(data); expect(result).toEqual({ meta: {} }); }); @@ -44,7 +44,7 @@ describe('getBruFileMeta', () => { seq: 1 }`; - const result = getBruFileMeta(data); + const result = parseBruFileMeta(data); expect(result).toEqual({ meta: { @@ -57,7 +57,7 @@ describe('getBruFileMeta', () => { test('handles unexpected input gracefully', () => { const data = null; - const result = getBruFileMeta(data); + const result = parseBruFileMeta(data); expect(result).toBeUndefined(); }); @@ -68,7 +68,7 @@ describe('getBruFileMeta', () => { seq: 1 }`; - const result = getBruFileMeta(data); + const result = parseBruFileMeta(data); expect(result).toEqual({ meta: { @@ -84,7 +84,7 @@ describe('getBruFileMeta', () => { strValue: some_text }`; - const result = getBruFileMeta(data); + const result = parseBruFileMeta(data); expect(result).toEqual({ meta: { @@ -102,7 +102,7 @@ describe('getBruFileMeta', () => { seq: 1 }`; - const result = getBruFileMeta(data); + const result = parseBruFileMeta(data); expect(result).toBeUndefined(); }); @@ -114,7 +114,7 @@ describe('getBruFileMeta', () => { seq: 1 `; - const result = getBruFileMeta(data); + const result = parseBruFileMeta(data); expect(result).toBeUndefined(); });