From 88aeb0e53016aed7a30425beb4452c026b023b0a Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 20 Jun 2024 08:40:10 -0700 Subject: [PATCH] Fix GRPC with files not refreshing, and tight render loop --- src-tauri/grpc/src/manager.rs | 28 +++++--- src-tauri/src/lib.rs | 8 +-- src-web/components/App.tsx | 5 +- src-web/components/CommandPalette.tsx | 4 +- src-web/components/ExportDataDialog.tsx | 4 +- src-web/components/GraphQLEditor.tsx | 1 - src-web/components/GrpcConnectionLayout.tsx | 10 +-- .../components/Settings/SettingsDesign.tsx | 6 +- src-web/components/SettingsDropdown.tsx | 4 +- src-web/hooks/useAppInfo.ts | 4 +- src-web/hooks/useCheckForUpdates.tsx | 4 +- src-web/hooks/useCookieJars.ts | 4 +- src-web/hooks/useCopyAsCurl.tsx | 4 +- src-web/hooks/useCreateCookieJar.ts | 4 +- src-web/hooks/useCreateEnvironment.ts | 4 +- src-web/hooks/useCreateFolder.ts | 4 +- src-web/hooks/useCreateGrpcRequest.ts | 4 +- src-web/hooks/useCreateHttpRequest.ts | 4 +- src-web/hooks/useCreateWorkspace.ts | 4 +- src-web/hooks/useDeleteAnyGrpcRequest.tsx | 4 +- src-web/hooks/useDeleteAnyHttpRequest.tsx | 4 +- src-web/hooks/useDeleteCookieJar.tsx | 4 +- src-web/hooks/useDeleteEnvironment.tsx | 4 +- src-web/hooks/useDeleteFolder.tsx | 4 +- src-web/hooks/useDeleteGrpcConnection.ts | 4 +- src-web/hooks/useDeleteGrpcConnections.ts | 4 +- src-web/hooks/useDeleteHttpResponse.ts | 4 +- src-web/hooks/useDeleteHttpResponses.ts | 4 +- src-web/hooks/useDeleteWorkspace.tsx | 4 +- src-web/hooks/useDuplicateGrpcRequest.ts | 4 +- src-web/hooks/useDuplicateHttpRequest.ts | 4 +- src-web/hooks/useEnvironments.ts | 4 +- src-web/hooks/useFilterResponse.ts | 4 +- src-web/hooks/useFolders.ts | 4 +- src-web/hooks/useGrpc.ts | 14 ++-- src-web/hooks/useGrpcConnections.ts | 4 +- src-web/hooks/useGrpcEvents.ts | 4 +- src-web/hooks/useGrpcRequests.ts | 4 +- src-web/hooks/useHttpRequests.ts | 4 +- src-web/hooks/useHttpResponses.ts | 4 +- src-web/hooks/useImportCurl.ts | 4 +- src-web/hooks/useImportData.tsx | 4 +- src-web/hooks/useNotificationToast.tsx | 4 +- src-web/hooks/useOpenWorkspace.ts | 4 +- src-web/hooks/useSaveResponse.tsx | 4 +- src-web/hooks/useSendAnyRequest.ts | 4 +- src-web/hooks/useSettings.ts | 4 +- src-web/hooks/useUpdateAnyFolder.ts | 4 +- src-web/hooks/useUpdateAnyGrpcRequest.ts | 4 +- src-web/hooks/useUpdateAnyHttpRequest.ts | 4 +- src-web/hooks/useUpdateCookieJar.ts | 4 +- src-web/hooks/useUpdateEnvironment.ts | 4 +- src-web/hooks/useUpdateSettings.ts | 4 +- src-web/hooks/useUpdateWorkspace.ts | 4 +- src-web/hooks/useVariables.ts | 18 ----- src-web/hooks/useWorkspaces.ts | 4 +- src-web/lib/analytics.ts | 4 +- src-web/lib/keyValueStore.ts | 6 +- src-web/lib/sendEphemeralRequest.ts | 4 +- src-web/lib/store.ts | 16 ++--- src-web/lib/tauri.ts | 70 +++++++++++++++++++ src-web/main.tsx | 2 +- 62 files changed, 221 insertions(+), 163 deletions(-) delete mode 100644 src-web/hooks/useVariables.ts create mode 100644 src-web/lib/tauri.ts diff --git a/src-tauri/grpc/src/manager.rs b/src-tauri/grpc/src/manager.rs index fe9edd47..fcc3e9c5 100644 --- a/src-tauri/grpc/src/manager.rs +++ b/src-tauri/grpc/src/manager.rs @@ -185,29 +185,39 @@ impl GrpcHandle { pub async fn services_from_files( &mut self, id: &str, - uri: &str, paths: Vec, ) -> Result, String> { + let pool_key = format!( + "{}-{}", + id, + paths + .iter() + .map(|p| p.to_string_lossy().to_string()) + .collect::>() + .join(":") + ); let pool = fill_pool_from_files(&self.app_handle, paths).await?; - let uri = uri_from_str(uri)?; - self.pools.insert(self.get_pool_key(id, &uri), pool.clone()); + self.pools.insert(pool_key, pool.clone()); Ok(self.services_from_pool(&pool)) } + pub async fn services_from_reflection( &mut self, id: &str, uri: &str, ) -> Result, String> { + // Short-circuit if no URL is set + if uri.is_empty() { + return Ok(Vec::new()); + } + let uri = uri_from_str(uri)?; let pool = fill_pool(&uri).await?; - self.pools.insert(self.get_pool_key(id, &uri), pool.clone()); + let pool_key = format!("{}-{}", id, uri); + self.pools.insert(pool_key, pool.clone()); Ok(self.services_from_pool(&pool)) } - fn get_pool_key(&self, id: &str, uri: &Uri) -> String { - format!("{}-{}", id, uri) - } - fn services_from_pool(&self, pool: &DescriptorPool) -> Vec { pool.services() .map(|s| { @@ -274,6 +284,6 @@ fn uri_from_str(uri_str: &str) -> Result { Err(err) => { // Uri::from_str basically only returns "invalid format" so we add more context here Err(format!("Failed to parse URL, {}", err.to_string())) - }, + } } } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index f08af614..25bca2b2 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -134,12 +134,7 @@ async fn cmd_grpc_reflect( let req = get_grpc_request(&window, request_id) .await .map_err(|e| e.to_string())?; - - // Short-circuit if no URL is set - if req.url.is_empty() { - return Ok(Vec::new()); - } - + let uri = safe_uri(req.url.as_str()); if proto_files.len() > 0 { grpc_handle @@ -147,7 +142,6 @@ async fn cmd_grpc_reflect( .await .services_from_files( &req.id, - uri.as_str(), proto_files .iter() .map(|p| PathBuf::from_str(p).unwrap()) diff --git a/src-web/components/App.tsx b/src-web/components/App.tsx index 5f1f0369..35cec5e9 100644 --- a/src-web/components/App.tsx +++ b/src-web/components/App.tsx @@ -1,6 +1,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import { MotionConfig } from 'framer-motion'; -import { Suspense } from 'react'; +import React, { Suspense } from 'react'; import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; import { HelmetProvider } from 'react-helmet-async'; @@ -19,12 +20,12 @@ const queryClient = new QueryClient({ export function App() { return ( + - {/**/} diff --git a/src-web/components/CommandPalette.tsx b/src-web/components/CommandPalette.tsx index 4779ed92..ccfbf7ad 100644 --- a/src-web/components/CommandPalette.tsx +++ b/src-web/components/CommandPalette.tsx @@ -1,4 +1,3 @@ -import { invoke } from '@tauri-apps/api/core'; import classNames from 'classnames'; import { search } from 'fast-fuzzy'; import type { KeyboardEvent, ReactNode } from 'react'; @@ -25,6 +24,7 @@ import { useRequests } from '../hooks/useRequests'; import { useSidebarHidden } from '../hooks/useSidebarHidden'; import { useWorkspaces } from '../hooks/useWorkspaces'; import { fallbackRequestName } from '../lib/fallbackRequestName'; +import { invokeCmd } from '../lib/tauri'; import { CookieDialog } from './CookieDialog'; import { Button } from './core/Button'; import { Heading } from './core/Heading'; @@ -82,7 +82,7 @@ export function CommandPalette({ onClose }: { onClose: () => void }) { action: 'settings.show', onSelect: async () => { if (workspaceId == null) return; - await invoke('cmd_new_nested_window', { + await invokeCmd('cmd_new_nested_window', { url: routes.paths.workspaceSettings({ workspaceId }), label: 'settings', title: 'Yaak Settings', diff --git a/src-web/components/ExportDataDialog.tsx b/src-web/components/ExportDataDialog.tsx index fdd1b5b9..ddb6f7c9 100644 --- a/src-web/components/ExportDataDialog.tsx +++ b/src-web/components/ExportDataDialog.tsx @@ -1,9 +1,9 @@ -import { invoke } from '@tauri-apps/api/core'; import { save } from '@tauri-apps/plugin-dialog'; import { useCallback, useMemo, useState } from 'react'; import slugify from 'slugify'; import type { Workspace } from '../lib/models'; import { count } from '../lib/pluralize'; +import { invokeCmd } from '../lib/tauri'; import { Button } from './core/Button'; import { Checkbox } from './core/Checkbox'; import { HStack, VStack } from './core/Stacks'; @@ -49,7 +49,7 @@ export function ExportDataDialog({ return; } - await invoke('cmd_export_data', { workspaceIds: ids, exportPath }); + await invokeCmd('cmd_export_data', { workspaceIds: ids, exportPath }); onHide(); onSuccess(exportPath); }, [onHide, onSuccess, selectedWorkspaces, workspaces]); diff --git a/src-web/components/GraphQLEditor.tsx b/src-web/components/GraphQLEditor.tsx index 52edbb82..7f56a8d9 100644 --- a/src-web/components/GraphQLEditor.tsx +++ b/src-web/components/GraphQLEditor.tsx @@ -66,7 +66,6 @@ export function GraphQLEditor({ defaultValue, onChange, baseRequest, ...extraEdi // Refetch the schema when the URL changes useEffect(() => { if (editorViewRef.current === null) return; - console.log('SET SCHEMA', schema); updateSchema(editorViewRef.current, schema ?? undefined); }, [schema]); diff --git a/src-web/components/GrpcConnectionLayout.tsx b/src-web/components/GrpcConnectionLayout.tsx index 039266a1..f777306b 100644 --- a/src-web/components/GrpcConnectionLayout.tsx +++ b/src-web/components/GrpcConnectionLayout.tsx @@ -17,14 +17,16 @@ interface Props { style: CSSProperties; } +const emptyArray: string[] = []; + export function GrpcConnectionLayout({ style }: Props) { const activeRequest = useActiveRequest('grpc_request'); - const updateRequest = useUpdateGrpcRequest(activeRequest?.id ?? null); + const { mutateAsync: updateRequest } = useUpdateGrpcRequest(activeRequest?.id ?? null); const connections = useGrpcConnections(activeRequest?.id ?? null); const activeConnection = connections[0] ?? null; const messages = useGrpcEvents(activeConnection?.id ?? null); const protoFilesKv = useGrpcProtoFiles(activeRequest?.id ?? null); - const protoFiles = protoFilesKv.value ?? []; + const protoFiles = protoFilesKv.value ?? emptyArray; const grpc = useGrpc(activeRequest, activeConnection, protoFiles); const services = grpc.reflect.data ?? null; @@ -32,7 +34,7 @@ export function GrpcConnectionLayout({ style }: Props) { if (services == null || activeRequest == null) return; const s = services.find((s) => s.name === activeRequest.service); if (s == null) { - updateRequest.mutate({ + updateRequest({ service: services[0]?.name ?? null, method: services[0]?.methods[0]?.name ?? null, }); @@ -41,7 +43,7 @@ export function GrpcConnectionLayout({ style }: Props) { const m = s.methods.find((m) => m.name === activeRequest.method); if (m == null) { - updateRequest.mutate({ method: s.methods[0]?.name ?? null }); + updateRequest({ method: s.methods[0]?.name ?? null }); return; } }, [activeRequest, services, updateRequest]); diff --git a/src-web/components/Settings/SettingsDesign.tsx b/src-web/components/Settings/SettingsDesign.tsx index 3d11248f..1725fa7c 100644 --- a/src-web/components/Settings/SettingsDesign.tsx +++ b/src-web/components/Settings/SettingsDesign.tsx @@ -1,9 +1,9 @@ -import { invoke } from '@tauri-apps/api/core'; import { open } from '@tauri-apps/plugin-dialog'; import React, { useState } from 'react'; import { useLocalStorage } from 'react-use'; import { useThemes } from '../../hooks/useThemes'; import { capitalize } from '../../lib/capitalize'; +import { invokeCmd } from '../../lib/tauri'; import { yaakDark } from '../../lib/theme/themes/yaak'; import { getThemeCSS } from '../../lib/theme/window'; import { Banner } from '../core/Banner'; @@ -58,11 +58,11 @@ export function SettingsDesign() { const coreThemeCSS = [yaakDark].map(getThemeCSS).join('\n\n'); try { - await invoke('cmd_write_file_dev', { + await invokeCmd('cmd_write_file_dev', { pathname: exportDir + '/themes-all.css', contents: allThemesCSS, }); - await invoke('cmd_write_file_dev', { + await invokeCmd('cmd_write_file_dev', { pathname: exportDir + '/themes-slim.css', contents: coreThemeCSS, }); diff --git a/src-web/components/SettingsDropdown.tsx b/src-web/components/SettingsDropdown.tsx index 15864aab..50319f3a 100644 --- a/src-web/components/SettingsDropdown.tsx +++ b/src-web/components/SettingsDropdown.tsx @@ -1,4 +1,3 @@ -import { invoke } from '@tauri-apps/api/core'; import { open } from '@tauri-apps/plugin-shell'; import { useRef } from 'react'; import { useActiveWorkspaceId } from '../hooks/useActiveWorkspaceId'; @@ -8,6 +7,7 @@ import { useCheckForUpdates } from '../hooks/useCheckForUpdates'; import { useExportData } from '../hooks/useExportData'; import { useImportData } from '../hooks/useImportData'; import { useListenToTauriEvent } from '../hooks/useListenToTauriEvent'; +import { invokeCmd } from '../lib/tauri'; import type { DropdownRef } from './core/Dropdown'; import { Dropdown } from './core/Dropdown'; import { Icon } from './core/Icon'; @@ -27,7 +27,7 @@ export function SettingsDropdown() { const showSettings = async () => { if (!workspaceId) return; - await invoke('cmd_new_nested_window', { + await invokeCmd('cmd_new_nested_window', { url: routes.paths.workspaceSettings({ workspaceId }), label: 'settings', title: 'Yaak Settings', diff --git a/src-web/hooks/useAppInfo.ts b/src-web/hooks/useAppInfo.ts index 19b0a648..01477415 100644 --- a/src-web/hooks/useAppInfo.ts +++ b/src-web/hooks/useAppInfo.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; +import { invokeCmd } from '../lib/tauri'; export interface AppInfo { isDev: boolean; @@ -13,7 +13,7 @@ export function useAppInfo() { return useQuery({ queryKey: ['appInfo'], queryFn: async () => { - const metadata = await invoke('cmd_metadata'); + const metadata = await invokeCmd('cmd_metadata'); return metadata as AppInfo; }, }).data; diff --git a/src-web/hooks/useCheckForUpdates.tsx b/src-web/hooks/useCheckForUpdates.tsx index 3a2f475a..51dadb9d 100644 --- a/src-web/hooks/useCheckForUpdates.tsx +++ b/src-web/hooks/useCheckForUpdates.tsx @@ -1,7 +1,7 @@ import { useMutation } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { InlineCode } from '../components/core/InlineCode'; import { minPromiseMillis } from '../lib/minPromiseMillis'; +import { invokeCmd } from '../lib/tauri'; import { useAlert } from './useAlert'; import { useAppInfo } from './useAppInfo'; @@ -10,7 +10,7 @@ export function useCheckForUpdates() { const appInfo = useAppInfo(); return useMutation({ mutationFn: async () => { - const hasUpdate: boolean = await minPromiseMillis(invoke('cmd_check_for_updates'), 500); + const hasUpdate: boolean = await minPromiseMillis(invokeCmd('cmd_check_for_updates'), 500); if (!hasUpdate) { alert({ id: 'no-updates', diff --git a/src-web/hooks/useCookieJars.ts b/src-web/hooks/useCookieJars.ts index 73db7ed3..d17e0303 100644 --- a/src-web/hooks/useCookieJars.ts +++ b/src-web/hooks/useCookieJars.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { CookieJar } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useActiveWorkspaceId } from './useActiveWorkspaceId'; export function cookieJarsQueryKey({ workspaceId }: { workspaceId: string }) { @@ -15,7 +15,7 @@ export function useCookieJars() { queryKey: cookieJarsQueryKey({ workspaceId: workspaceId ?? 'n/a' }), queryFn: async () => { if (workspaceId == null) return []; - return (await invoke('cmd_list_cookie_jars', { workspaceId })) as CookieJar[]; + return (await invokeCmd('cmd_list_cookie_jars', { workspaceId })) as CookieJar[]; }, }).data ?? [] ); diff --git a/src-web/hooks/useCopyAsCurl.tsx b/src-web/hooks/useCopyAsCurl.tsx index bdf0a81d..2a6d6df4 100644 --- a/src-web/hooks/useCopyAsCurl.tsx +++ b/src-web/hooks/useCopyAsCurl.tsx @@ -1,4 +1,4 @@ -import { invoke } from '@tauri-apps/api/core'; +import { invokeCmd } from '../lib/tauri'; import { useActiveEnvironmentId } from './useActiveEnvironmentId'; import { useClipboardText } from './useClipboardText'; @@ -6,7 +6,7 @@ export function useCopyAsCurl(requestId: string) { const [, copy] = useClipboardText(); const environmentId = useActiveEnvironmentId(); return async () => { - const cmd: string = await invoke('cmd_request_to_curl', { requestId, environmentId }); + const cmd: string = await invokeCmd('cmd_request_to_curl', { requestId, environmentId }); copy(cmd); return cmd; }; diff --git a/src-web/hooks/useCreateCookieJar.ts b/src-web/hooks/useCreateCookieJar.ts index 6c5beb23..1a1fa241 100644 --- a/src-web/hooks/useCreateCookieJar.ts +++ b/src-web/hooks/useCreateCookieJar.ts @@ -1,7 +1,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { trackEvent } from '../lib/analytics'; import type { CookieJar } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useActiveWorkspaceId } from './useActiveWorkspaceId'; import { cookieJarsQueryKey } from './useCookieJars'; import { usePrompt } from './usePrompt'; @@ -24,7 +24,7 @@ export function useCreateCookieJar() { label: 'Name', defaultValue: 'My Jar', }); - return invoke('cmd_create_cookie_jar', { workspaceId, name }); + return invokeCmd('cmd_create_cookie_jar', { workspaceId, name }); }, onSettled: () => trackEvent('cookie_jar', 'create'), onSuccess: async (cookieJar) => { diff --git a/src-web/hooks/useCreateEnvironment.ts b/src-web/hooks/useCreateEnvironment.ts index f0d4d037..f6679711 100644 --- a/src-web/hooks/useCreateEnvironment.ts +++ b/src-web/hooks/useCreateEnvironment.ts @@ -1,7 +1,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { trackEvent } from '../lib/analytics'; import type { Environment } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useActiveWorkspaceId } from './useActiveWorkspaceId'; import { useAppRoutes } from './useAppRoutes'; import { environmentsQueryKey } from './useEnvironments'; @@ -24,7 +24,7 @@ export function useCreateEnvironment() { placeholder: 'My Environment', defaultValue: 'My Environment', }); - return invoke('cmd_create_environment', { name, variables: [], workspaceId }); + return invokeCmd('cmd_create_environment', { name, variables: [], workspaceId }); }, onSettled: () => trackEvent('environment', 'create'), onSuccess: async (environment) => { diff --git a/src-web/hooks/useCreateFolder.ts b/src-web/hooks/useCreateFolder.ts index 9a6735d4..5fa9c1cc 100644 --- a/src-web/hooks/useCreateFolder.ts +++ b/src-web/hooks/useCreateFolder.ts @@ -1,7 +1,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { trackEvent } from '../lib/analytics'; import type { Folder } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useActiveRequest } from './useActiveRequest'; import { useActiveWorkspaceId } from './useActiveWorkspaceId'; import { foldersQueryKey } from './useFolders'; @@ -31,7 +31,7 @@ export function useCreateFolder() { })); patch.sortPriority = patch.sortPriority || -Date.now(); patch.folderId = patch.folderId || activeRequest?.folderId; - return invoke('cmd_create_folder', { workspaceId, ...patch }); + return invokeCmd('cmd_create_folder', { workspaceId, ...patch }); }, onSettled: () => trackEvent('folder', 'create'), onSuccess: async (request) => { diff --git a/src-web/hooks/useCreateGrpcRequest.ts b/src-web/hooks/useCreateGrpcRequest.ts index fcae3ca3..31e1db94 100644 --- a/src-web/hooks/useCreateGrpcRequest.ts +++ b/src-web/hooks/useCreateGrpcRequest.ts @@ -1,7 +1,7 @@ import { useMutation } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { trackEvent } from '../lib/analytics'; import type { GrpcRequest } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useActiveEnvironmentId } from './useActiveEnvironmentId'; import { useActiveRequest } from './useActiveRequest'; import { useActiveWorkspaceId } from './useActiveWorkspaceId'; @@ -32,7 +32,7 @@ export function useCreateGrpcRequest() { } } patch.folderId = patch.folderId || activeRequest?.folderId; - return invoke('cmd_create_grpc_request', { workspaceId, name: '', ...patch }); + return invokeCmd('cmd_create_grpc_request', { workspaceId, name: '', ...patch }); }, onSettled: () => trackEvent('grpc_request', 'create'), onSuccess: async (request) => { diff --git a/src-web/hooks/useCreateHttpRequest.ts b/src-web/hooks/useCreateHttpRequest.ts index 2ac8c925..9bb3b3b9 100644 --- a/src-web/hooks/useCreateHttpRequest.ts +++ b/src-web/hooks/useCreateHttpRequest.ts @@ -1,7 +1,7 @@ import { useMutation } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { trackEvent } from '../lib/analytics'; import type { HttpRequest } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useActiveEnvironmentId } from './useActiveEnvironmentId'; import { useActiveRequest } from './useActiveRequest'; import { useActiveWorkspaceId } from './useActiveWorkspaceId'; @@ -28,7 +28,7 @@ export function useCreateHttpRequest() { } } patch.folderId = patch.folderId || activeRequest?.folderId; - return invoke('cmd_create_http_request', { request: { workspaceId, ...patch } }); + return invokeCmd('cmd_create_http_request', { request: { workspaceId, ...patch } }); }, onSettled: () => trackEvent('http_request', 'create'), onSuccess: async (request) => { diff --git a/src-web/hooks/useCreateWorkspace.ts b/src-web/hooks/useCreateWorkspace.ts index 7d32d622..6fa4a8cf 100644 --- a/src-web/hooks/useCreateWorkspace.ts +++ b/src-web/hooks/useCreateWorkspace.ts @@ -1,6 +1,6 @@ import { useMutation } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { Workspace } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useAppRoutes } from './useAppRoutes'; import { usePrompt } from './usePrompt'; @@ -18,7 +18,7 @@ export function useCreateWorkspace() { confirmLabel: 'Create', placeholder: 'My Workspace', }); - return invoke('cmd_create_workspace', { name }); + return invokeCmd('cmd_create_workspace', { name }); }, onSuccess: async (workspace) => { routes.navigate('workspace', { workspaceId: workspace.id }); diff --git a/src-web/hooks/useDeleteAnyGrpcRequest.tsx b/src-web/hooks/useDeleteAnyGrpcRequest.tsx index 5f60c54b..84d65664 100644 --- a/src-web/hooks/useDeleteAnyGrpcRequest.tsx +++ b/src-web/hooks/useDeleteAnyGrpcRequest.tsx @@ -1,10 +1,10 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { InlineCode } from '../components/core/InlineCode'; import { trackEvent } from '../lib/analytics'; import { fallbackRequestName } from '../lib/fallbackRequestName'; import type { GrpcRequest } from '../lib/models'; import { getGrpcRequest } from '../lib/store'; +import { invokeCmd } from '../lib/tauri'; import { useConfirm } from './useConfirm'; import { grpcRequestsQueryKey } from './useGrpcRequests'; @@ -28,7 +28,7 @@ export function useDeleteAnyGrpcRequest() { ), }); if (!confirmed) return null; - return invoke('cmd_delete_grpc_request', { requestId: id }); + return invokeCmd('cmd_delete_grpc_request', { requestId: id }); }, onSettled: () => trackEvent('grpc_request', 'delete'), onSuccess: async (request) => { diff --git a/src-web/hooks/useDeleteAnyHttpRequest.tsx b/src-web/hooks/useDeleteAnyHttpRequest.tsx index 3db07e4a..a9c41a6e 100644 --- a/src-web/hooks/useDeleteAnyHttpRequest.tsx +++ b/src-web/hooks/useDeleteAnyHttpRequest.tsx @@ -1,10 +1,10 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { InlineCode } from '../components/core/InlineCode'; import { trackEvent } from '../lib/analytics'; import { fallbackRequestName } from '../lib/fallbackRequestName'; import type { HttpRequest } from '../lib/models'; import { getHttpRequest } from '../lib/store'; +import { invokeCmd } from '../lib/tauri'; import { useConfirm } from './useConfirm'; import { httpRequestsQueryKey } from './useHttpRequests'; import { httpResponsesQueryKey } from './useHttpResponses'; @@ -29,7 +29,7 @@ export function useDeleteAnyHttpRequest() { ), }); if (!confirmed) return null; - return invoke('cmd_delete_http_request', { requestId: id }); + return invokeCmd('cmd_delete_http_request', { requestId: id }); }, onSettled: () => trackEvent('http_request', 'delete'), onSuccess: async (request) => { diff --git a/src-web/hooks/useDeleteCookieJar.tsx b/src-web/hooks/useDeleteCookieJar.tsx index b46ec83a..e95389ed 100644 --- a/src-web/hooks/useDeleteCookieJar.tsx +++ b/src-web/hooks/useDeleteCookieJar.tsx @@ -1,8 +1,8 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { InlineCode } from '../components/core/InlineCode'; import { trackEvent } from '../lib/analytics'; import type { CookieJar } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useConfirm } from './useConfirm'; import { cookieJarsQueryKey } from './useCookieJars'; @@ -23,7 +23,7 @@ export function useDeleteCookieJar(cookieJar: CookieJar | null) { ), }); if (!confirmed) return null; - return invoke('cmd_delete_cookie_jar', { cookieJarId: cookieJar?.id }); + return invokeCmd('cmd_delete_cookie_jar', { cookieJarId: cookieJar?.id }); }, onSettled: () => trackEvent('cookie_jar', 'delete'), onSuccess: async (cookieJar) => { diff --git a/src-web/hooks/useDeleteEnvironment.tsx b/src-web/hooks/useDeleteEnvironment.tsx index db034569..c4d626dd 100644 --- a/src-web/hooks/useDeleteEnvironment.tsx +++ b/src-web/hooks/useDeleteEnvironment.tsx @@ -1,8 +1,8 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { InlineCode } from '../components/core/InlineCode'; import { trackEvent } from '../lib/analytics'; import type { Environment, Workspace } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useConfirm } from './useConfirm'; import { environmentsQueryKey } from './useEnvironments'; @@ -23,7 +23,7 @@ export function useDeleteEnvironment(environment: Environment | null) { ), }); if (!confirmed) return null; - return invoke('cmd_delete_environment', { environmentId: environment?.id }); + return invokeCmd('cmd_delete_environment', { environmentId: environment?.id }); }, onSettled: () => trackEvent('environment', 'delete'), onSuccess: async (environment) => { diff --git a/src-web/hooks/useDeleteFolder.tsx b/src-web/hooks/useDeleteFolder.tsx index 51333d6f..e03f98e4 100644 --- a/src-web/hooks/useDeleteFolder.tsx +++ b/src-web/hooks/useDeleteFolder.tsx @@ -1,9 +1,9 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { InlineCode } from '../components/core/InlineCode'; import { trackEvent } from '../lib/analytics'; import type { Folder } from '../lib/models'; import { getFolder } from '../lib/store'; +import { invokeCmd } from '../lib/tauri'; import { useConfirm } from './useConfirm'; import { foldersQueryKey } from './useFolders'; import { httpRequestsQueryKey } from './useHttpRequests'; @@ -26,7 +26,7 @@ export function useDeleteFolder(id: string | null) { ), }); if (!confirmed) return null; - return invoke('cmd_delete_folder', { folderId: id }); + return invokeCmd('cmd_delete_folder', { folderId: id }); }, onSettled: () => trackEvent('folder', 'delete'), onSuccess: async (folder) => { diff --git a/src-web/hooks/useDeleteGrpcConnection.ts b/src-web/hooks/useDeleteGrpcConnection.ts index d0609483..e877a95e 100644 --- a/src-web/hooks/useDeleteGrpcConnection.ts +++ b/src-web/hooks/useDeleteGrpcConnection.ts @@ -1,14 +1,14 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { trackEvent } from '../lib/analytics'; import type { GrpcConnection } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { grpcConnectionsQueryKey } from './useGrpcConnections'; export function useDeleteGrpcConnection(id: string | null) { const queryClient = useQueryClient(); return useMutation({ mutationFn: async () => { - return await invoke('cmd_delete_grpc_connection', { id: id }); + return await invokeCmd('cmd_delete_grpc_connection', { id: id }); }, onSettled: () => trackEvent('grpc_connection', 'delete'), onSuccess: ({ requestId, id: connectionId }) => { diff --git a/src-web/hooks/useDeleteGrpcConnections.ts b/src-web/hooks/useDeleteGrpcConnections.ts index 75f214b4..416a0772 100644 --- a/src-web/hooks/useDeleteGrpcConnections.ts +++ b/src-web/hooks/useDeleteGrpcConnections.ts @@ -1,6 +1,6 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { trackEvent } from '../lib/analytics'; +import { invokeCmd } from '../lib/tauri'; import { grpcConnectionsQueryKey } from './useGrpcConnections'; export function useDeleteGrpcConnections(requestId?: string) { @@ -8,7 +8,7 @@ export function useDeleteGrpcConnections(requestId?: string) { return useMutation({ mutationFn: async () => { if (requestId === undefined) return; - await invoke('cmd_delete_all_grpc_connections', { requestId }); + await invokeCmd('cmd_delete_all_grpc_connections', { requestId }); }, onSettled: () => trackEvent('grpc_connection', 'delete_many'), onSuccess: async () => { diff --git a/src-web/hooks/useDeleteHttpResponse.ts b/src-web/hooks/useDeleteHttpResponse.ts index d7349615..25f82201 100644 --- a/src-web/hooks/useDeleteHttpResponse.ts +++ b/src-web/hooks/useDeleteHttpResponse.ts @@ -1,14 +1,14 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { trackEvent } from '../lib/analytics'; import type { HttpResponse } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { httpResponsesQueryKey } from './useHttpResponses'; export function useDeleteHttpResponse(id: string | null) { const queryClient = useQueryClient(); return useMutation({ mutationFn: async () => { - return await invoke('cmd_delete_http_response', { id: id }); + return await invokeCmd('cmd_delete_http_response', { id: id }); }, onSettled: () => trackEvent('http_response', 'delete'), onSuccess: ({ requestId, id: responseId }) => { diff --git a/src-web/hooks/useDeleteHttpResponses.ts b/src-web/hooks/useDeleteHttpResponses.ts index 4523e83a..291f1dfc 100644 --- a/src-web/hooks/useDeleteHttpResponses.ts +++ b/src-web/hooks/useDeleteHttpResponses.ts @@ -1,6 +1,6 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { trackEvent } from '../lib/analytics'; +import { invokeCmd } from '../lib/tauri'; import { httpResponsesQueryKey } from './useHttpResponses'; export function useDeleteHttpResponses(requestId?: string) { @@ -8,7 +8,7 @@ export function useDeleteHttpResponses(requestId?: string) { return useMutation({ mutationFn: async () => { if (requestId === undefined) return; - await invoke('cmd_delete_all_http_responses', { requestId }); + await invokeCmd('cmd_delete_all_http_responses', { requestId }); }, onSettled: () => trackEvent('http_response', 'delete_many'), onSuccess: async () => { diff --git a/src-web/hooks/useDeleteWorkspace.tsx b/src-web/hooks/useDeleteWorkspace.tsx index 5ce8e039..39de3936 100644 --- a/src-web/hooks/useDeleteWorkspace.tsx +++ b/src-web/hooks/useDeleteWorkspace.tsx @@ -1,8 +1,8 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { InlineCode } from '../components/core/InlineCode'; import { trackEvent } from '../lib/analytics'; import type { Workspace } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useActiveWorkspaceId } from './useActiveWorkspaceId'; import { useAppRoutes } from './useAppRoutes'; import { useConfirm } from './useConfirm'; @@ -28,7 +28,7 @@ export function useDeleteWorkspace(workspace: Workspace | null) { ), }); if (!confirmed) return null; - return invoke('cmd_delete_workspace', { workspaceId: workspace?.id }); + return invokeCmd('cmd_delete_workspace', { workspaceId: workspace?.id }); }, onSettled: () => trackEvent('workspace', 'delete'), onSuccess: async (workspace) => { diff --git a/src-web/hooks/useDuplicateGrpcRequest.ts b/src-web/hooks/useDuplicateGrpcRequest.ts index 361043f0..8db63d47 100644 --- a/src-web/hooks/useDuplicateGrpcRequest.ts +++ b/src-web/hooks/useDuplicateGrpcRequest.ts @@ -1,8 +1,8 @@ import { useMutation } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { trackEvent } from '../lib/analytics'; import { setKeyValue } from '../lib/keyValueStore'; import type { GrpcRequest } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useActiveEnvironmentId } from './useActiveEnvironmentId'; import { useActiveWorkspaceId } from './useActiveWorkspaceId'; import { useAppRoutes } from './useAppRoutes'; @@ -22,7 +22,7 @@ export function useDuplicateGrpcRequest({ return useMutation({ mutationFn: async () => { if (id === null) throw new Error("Can't duplicate a null grpc request"); - return invoke('cmd_duplicate_grpc_request', { id }); + return invokeCmd('cmd_duplicate_grpc_request', { id }); }, onSettled: () => trackEvent('grpc_request', 'duplicate'), onSuccess: async (request) => { diff --git a/src-web/hooks/useDuplicateHttpRequest.ts b/src-web/hooks/useDuplicateHttpRequest.ts index 95028abb..20c9fb3a 100644 --- a/src-web/hooks/useDuplicateHttpRequest.ts +++ b/src-web/hooks/useDuplicateHttpRequest.ts @@ -1,7 +1,7 @@ import { useMutation } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { trackEvent } from '../lib/analytics'; import type { HttpRequest } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useActiveEnvironmentId } from './useActiveEnvironmentId'; import { useActiveWorkspaceId } from './useActiveWorkspaceId'; import { useAppRoutes } from './useAppRoutes'; @@ -19,7 +19,7 @@ export function useDuplicateHttpRequest({ return useMutation({ mutationFn: async () => { if (id === null) throw new Error("Can't duplicate a null request"); - return invoke('cmd_duplicate_http_request', { id }); + return invokeCmd('cmd_duplicate_http_request', { id }); }, onSettled: () => trackEvent('http_request', 'duplicate'), onSuccess: async (request) => { diff --git a/src-web/hooks/useEnvironments.ts b/src-web/hooks/useEnvironments.ts index 009aa2bc..5705e9de 100644 --- a/src-web/hooks/useEnvironments.ts +++ b/src-web/hooks/useEnvironments.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { Environment } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useActiveWorkspaceId } from './useActiveWorkspaceId'; export function environmentsQueryKey({ workspaceId }: { workspaceId: string }) { @@ -15,7 +15,7 @@ export function useEnvironments() { queryKey: environmentsQueryKey({ workspaceId: workspaceId ?? 'n/a' }), queryFn: async () => { if (workspaceId == null) return []; - return (await invoke('cmd_list_environments', { workspaceId })) as Environment[]; + return (await invokeCmd('cmd_list_environments', { workspaceId })) as Environment[]; }, }).data ?? [] ); diff --git a/src-web/hooks/useFilterResponse.ts b/src-web/hooks/useFilterResponse.ts index 25031e14..84e51ed2 100644 --- a/src-web/hooks/useFilterResponse.ts +++ b/src-web/hooks/useFilterResponse.ts @@ -1,5 +1,5 @@ import { useQuery } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; +import { invokeCmd } from '../lib/tauri'; export function useFilterResponse({ responseId, @@ -16,7 +16,7 @@ export function useFilterResponse({ return null; } - return (await invoke('cmd_filter_response', { responseId, filter })) as string | null; + return (await invokeCmd('cmd_filter_response', { responseId, filter })) as string | null; }, }).data ?? '' ); diff --git a/src-web/hooks/useFolders.ts b/src-web/hooks/useFolders.ts index 473e087c..440ba5b4 100644 --- a/src-web/hooks/useFolders.ts +++ b/src-web/hooks/useFolders.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { Folder } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useActiveWorkspaceId } from './useActiveWorkspaceId'; export function foldersQueryKey({ workspaceId }: { workspaceId: string }) { @@ -15,7 +15,7 @@ export function useFolders() { queryKey: foldersQueryKey({ workspaceId: workspaceId ?? 'n/a' }), queryFn: async () => { if (workspaceId == null) return []; - return (await invoke('cmd_list_folders', { workspaceId })) as Folder[]; + return (await invokeCmd('cmd_list_folders', { workspaceId })) as Folder[]; }, }).data ?? [] ); diff --git a/src-web/hooks/useGrpc.ts b/src-web/hooks/useGrpc.ts index 250d20dc..4d755b71 100644 --- a/src-web/hooks/useGrpc.ts +++ b/src-web/hooks/useGrpc.ts @@ -1,9 +1,9 @@ import { useMutation, useQuery } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { emit } from '@tauri-apps/api/event'; import { trackEvent } from '../lib/analytics'; import { minPromiseMillis } from '../lib/minPromiseMillis'; import type { GrpcConnection, GrpcRequest } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useActiveEnvironmentId } from './useActiveEnvironmentId'; import { useDebouncedValue } from './useDebouncedValue'; @@ -21,7 +21,8 @@ export function useGrpc( const environmentId = useActiveEnvironmentId(); const go = useMutation({ - mutationFn: async () => await invoke('cmd_grpc_go', { requestId, environmentId, protoFiles }), + mutationFn: async () => + await invokeCmd('cmd_grpc_go', { requestId, environmentId, protoFiles }), onSettled: () => trackEvent('grpc_request', 'send'), }); @@ -48,12 +49,11 @@ export function useGrpc( enabled: req != null, queryKey: ['grpc_reflect', req?.id ?? 'n/a', debouncedUrl, protoFiles], refetchOnWindowFocus: false, - queryFn: async () => { - return (await minPromiseMillis( - invoke('cmd_grpc_reflect', { requestId, protoFiles }), + queryFn: async () => + (await minPromiseMillis( + invokeCmd('cmd_grpc_reflect', { requestId, protoFiles }), 300, - )) as ReflectResponseService[]; - }, + )) as ReflectResponseService[], }); return { diff --git a/src-web/hooks/useGrpcConnections.ts b/src-web/hooks/useGrpcConnections.ts index 21f553a9..a89e4943 100644 --- a/src-web/hooks/useGrpcConnections.ts +++ b/src-web/hooks/useGrpcConnections.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { GrpcConnection } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; export function grpcConnectionsQueryKey({ requestId }: { requestId: string }) { return ['grpc_connections', { requestId }]; @@ -13,7 +13,7 @@ export function useGrpcConnections(requestId: string | null) { initialData: [], queryKey: grpcConnectionsQueryKey({ requestId: requestId ?? 'n/a' }), queryFn: async () => { - return (await invoke('cmd_list_grpc_connections', { + return (await invokeCmd('cmd_list_grpc_connections', { requestId, limit: 200, })) as GrpcConnection[]; diff --git a/src-web/hooks/useGrpcEvents.ts b/src-web/hooks/useGrpcEvents.ts index a1c42707..7ada4427 100644 --- a/src-web/hooks/useGrpcEvents.ts +++ b/src-web/hooks/useGrpcEvents.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { GrpcEvent } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; export function grpcEventsQueryKey({ connectionId }: { connectionId: string }) { return ['grpc_events', { connectionId }]; @@ -13,7 +13,7 @@ export function useGrpcEvents(connectionId: string | null) { initialData: [], queryKey: grpcEventsQueryKey({ connectionId: connectionId ?? 'n/a' }), queryFn: async () => { - return (await invoke('cmd_list_grpc_events', { + return (await invokeCmd('cmd_list_grpc_events', { connectionId, limit: 200, })) as GrpcEvent[]; diff --git a/src-web/hooks/useGrpcRequests.ts b/src-web/hooks/useGrpcRequests.ts index 31845446..7c60d477 100644 --- a/src-web/hooks/useGrpcRequests.ts +++ b/src-web/hooks/useGrpcRequests.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { GrpcRequest } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useActiveWorkspaceId } from './useActiveWorkspaceId'; export function grpcRequestsQueryKey({ workspaceId }: { workspaceId: string }) { @@ -15,7 +15,7 @@ export function useGrpcRequests() { queryKey: grpcRequestsQueryKey({ workspaceId: workspaceId ?? 'n/a' }), queryFn: async () => { if (workspaceId == null) return []; - return (await invoke('cmd_list_grpc_requests', { workspaceId })) as GrpcRequest[]; + return (await invokeCmd('cmd_list_grpc_requests', { workspaceId })) as GrpcRequest[]; }, }).data ?? [] ); diff --git a/src-web/hooks/useHttpRequests.ts b/src-web/hooks/useHttpRequests.ts index a66328e9..ed467aa7 100644 --- a/src-web/hooks/useHttpRequests.ts +++ b/src-web/hooks/useHttpRequests.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { HttpRequest } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useActiveWorkspaceId } from './useActiveWorkspaceId'; export function httpRequestsQueryKey({ workspaceId }: { workspaceId: string }) { @@ -15,7 +15,7 @@ export function useHttpRequests() { queryKey: httpRequestsQueryKey({ workspaceId: workspaceId ?? 'n/a' }), queryFn: async () => { if (workspaceId == null) return []; - return (await invoke('cmd_list_http_requests', { workspaceId })) as HttpRequest[]; + return (await invokeCmd('cmd_list_http_requests', { workspaceId })) as HttpRequest[]; }, }).data ?? [] ); diff --git a/src-web/hooks/useHttpResponses.ts b/src-web/hooks/useHttpResponses.ts index 61c99a01..f7407022 100644 --- a/src-web/hooks/useHttpResponses.ts +++ b/src-web/hooks/useHttpResponses.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { HttpResponse } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; export function httpResponsesQueryKey({ requestId }: { requestId: string }) { return ['http_responses', { requestId }]; @@ -13,7 +13,7 @@ export function useHttpResponses(requestId: string | null) { initialData: [], queryKey: httpResponsesQueryKey({ requestId: requestId ?? 'n/a' }), queryFn: async () => { - return (await invoke('cmd_list_http_responses', { + return (await invokeCmd('cmd_list_http_responses', { requestId, limit: 200, })) as HttpResponse[]; diff --git a/src-web/hooks/useImportCurl.ts b/src-web/hooks/useImportCurl.ts index c5afce3b..15bac81d 100644 --- a/src-web/hooks/useImportCurl.ts +++ b/src-web/hooks/useImportCurl.ts @@ -1,5 +1,5 @@ -import { invoke } from '@tauri-apps/api/core'; import { useMutation } from '@tanstack/react-query'; +import { invokeCmd } from '../lib/tauri'; import { useActiveWorkspaceId } from './useActiveWorkspaceId'; import { useRequestUpdateKey } from './useRequestUpdateKey'; import { useUpdateAnyHttpRequest } from './useUpdateAnyHttpRequest'; @@ -17,7 +17,7 @@ export function useImportCurl({ clearClipboard }: { clearClipboard?: boolean } = return useMutation({ mutationFn: async ({ requestId, command }: { requestId: string | null; command: string }) => { - const request: Record = await invoke('cmd_curl_to_request', { + const request: Record = await invokeCmd('cmd_curl_to_request', { command, workspaceId, }); diff --git a/src-web/hooks/useImportData.tsx b/src-web/hooks/useImportData.tsx index 1788ac0e..3eeec7b6 100644 --- a/src-web/hooks/useImportData.tsx +++ b/src-web/hooks/useImportData.tsx @@ -1,5 +1,4 @@ import { useMutation } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { open } from '@tauri-apps/plugin-dialog'; import { Button } from '../components/core/Button'; import { FormattedError } from '../components/core/FormattedError'; @@ -7,6 +6,7 @@ import { VStack } from '../components/core/Stacks'; import { useDialog } from '../components/DialogContext'; import type { Environment, Folder, GrpcRequest, HttpRequest, Workspace } from '../lib/models'; import { count } from '../lib/pluralize'; +import { invokeCmd } from '../lib/tauri'; import { useActiveWorkspaceId } from './useActiveWorkspaceId'; import { useAlert } from './useAlert'; import { useAppRoutes } from './useAppRoutes'; @@ -33,7 +33,7 @@ export function useImportData() { folders: Folder[]; httpRequests: HttpRequest[]; grpcRequests: GrpcRequest[]; - } = await invoke('cmd_import_data', { + } = await invokeCmd('cmd_import_data', { filePath: selected.path, workspaceId: activeWorkspaceId, }); diff --git a/src-web/hooks/useNotificationToast.tsx b/src-web/hooks/useNotificationToast.tsx index e3a3d755..adb240dc 100644 --- a/src-web/hooks/useNotificationToast.tsx +++ b/src-web/hooks/useNotificationToast.tsx @@ -1,14 +1,14 @@ -import { invoke } from '@tauri-apps/api/core'; import { open } from '@tauri-apps/plugin-shell'; import { Button } from '../components/core/Button'; import { useToast } from '../components/ToastContext'; +import { invokeCmd } from '../lib/tauri'; import { useListenToTauriEvent } from './useListenToTauriEvent'; export function useNotificationToast() { const toast = useToast(); const markRead = (id: string) => { - invoke('cmd_dismiss_notification', { notificationId: id }).catch(console.error); + invokeCmd('cmd_dismiss_notification', { notificationId: id }).catch(console.error); }; useListenToTauriEvent<{ diff --git a/src-web/hooks/useOpenWorkspace.ts b/src-web/hooks/useOpenWorkspace.ts index ed4c5bd1..0762ea6e 100644 --- a/src-web/hooks/useOpenWorkspace.ts +++ b/src-web/hooks/useOpenWorkspace.ts @@ -1,5 +1,5 @@ import { useMutation } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; +import { invokeCmd } from '../lib/tauri'; import { useAppRoutes } from './useAppRoutes'; import { getRecentEnvironments } from './useRecentEnvironments'; import { getRecentRequests } from './useRecentRequests'; @@ -26,7 +26,7 @@ export function useOpenWorkspace() { requestId, }) : routes.paths.workspace({ workspaceId, environmentId }); - await invoke('cmd_new_window', { url: path }); + await invokeCmd('cmd_new_window', { url: path }); } else { const environmentId = (await getRecentEnvironments(workspaceId))[0]; const requestId = (await getRecentRequests(workspaceId))[0]; diff --git a/src-web/hooks/useSaveResponse.tsx b/src-web/hooks/useSaveResponse.tsx index 7b659385..8f2fea12 100644 --- a/src-web/hooks/useSaveResponse.tsx +++ b/src-web/hooks/useSaveResponse.tsx @@ -1,5 +1,4 @@ import { useMutation } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { save } from '@tauri-apps/plugin-dialog'; import mime from 'mime'; import slugify from 'slugify'; @@ -8,6 +7,7 @@ import { useToast } from '../components/ToastContext'; import type { HttpResponse } from '../lib/models'; import { getContentTypeHeader } from '../lib/models'; import { getHttpRequest } from '../lib/store'; +import { invokeCmd } from '../lib/tauri'; export function useSaveResponse(response: HttpResponse) { const toast = useToast(); @@ -24,7 +24,7 @@ export function useSaveResponse(response: HttpResponse) { defaultPath: ext ? `${slug}.${ext}` : slug, title: 'Save Response', }); - await invoke('cmd_save_response', { responseId: response.id, filepath }); + await invokeCmd('cmd_save_response', { responseId: response.id, filepath }); toast.show({ message: ( <> diff --git a/src-web/hooks/useSendAnyRequest.ts b/src-web/hooks/useSendAnyRequest.ts index 39867b1b..9e83c931 100644 --- a/src-web/hooks/useSendAnyRequest.ts +++ b/src-web/hooks/useSendAnyRequest.ts @@ -1,10 +1,10 @@ import { useMutation } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import { save } from '@tauri-apps/plugin-dialog'; import slugify from 'slugify'; import { trackEvent } from '../lib/analytics'; import type { HttpResponse } from '../lib/models'; import { getHttpRequest } from '../lib/store'; +import { invokeCmd } from '../lib/tauri'; import { useActiveCookieJar } from './useActiveCookieJar'; import { useActiveEnvironment } from './useActiveEnvironment'; import { useAlert } from './useAlert'; @@ -31,7 +31,7 @@ export function useSendAnyRequest(options: { download?: boolean } = {}) { } } - return invoke('cmd_send_http_request', { + return invokeCmd('cmd_send_http_request', { requestId: id, environmentId: environment?.id, downloadDir: downloadDir, diff --git a/src-web/hooks/useSettings.ts b/src-web/hooks/useSettings.ts index 47ba7b85..ca83c112 100644 --- a/src-web/hooks/useSettings.ts +++ b/src-web/hooks/useSettings.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { Settings } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; export function settingsQueryKey() { return ['settings']; @@ -11,7 +11,7 @@ export function useSettings() { useQuery({ queryKey: settingsQueryKey(), queryFn: async () => { - const settings = (await invoke('cmd_get_settings')) as Settings; + const settings = (await invokeCmd('cmd_get_settings')) as Settings; return [settings]; }, }).data?.[0] ?? undefined diff --git a/src-web/hooks/useUpdateAnyFolder.ts b/src-web/hooks/useUpdateAnyFolder.ts index c7c1cae8..f0bd057f 100644 --- a/src-web/hooks/useUpdateAnyFolder.ts +++ b/src-web/hooks/useUpdateAnyFolder.ts @@ -1,7 +1,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { Folder } from '../lib/models'; import { getFolder } from '../lib/store'; +import { invokeCmd } from '../lib/tauri'; import { foldersQueryKey } from './useFolders'; export function useUpdateAnyFolder() { @@ -14,7 +14,7 @@ export function useUpdateAnyFolder() { throw new Error("Can't update a null folder"); } - await invoke('cmd_update_folder', { folder: update(folder) }); + await invokeCmd('cmd_update_folder', { folder: update(folder) }); }, onMutate: async ({ id, update }) => { const folder = await getFolder(id); diff --git a/src-web/hooks/useUpdateAnyGrpcRequest.ts b/src-web/hooks/useUpdateAnyGrpcRequest.ts index 911197ad..ce3c6e17 100644 --- a/src-web/hooks/useUpdateAnyGrpcRequest.ts +++ b/src-web/hooks/useUpdateAnyGrpcRequest.ts @@ -1,7 +1,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { GrpcRequest } from '../lib/models'; import { getGrpcRequest } from '../lib/store'; +import { invokeCmd } from '../lib/tauri'; import { grpcRequestsQueryKey } from './useGrpcRequests'; export function useUpdateAnyGrpcRequest() { @@ -20,7 +20,7 @@ export function useUpdateAnyGrpcRequest() { const patchedRequest = typeof update === 'function' ? update(request) : { ...request, ...update }; - await invoke('cmd_update_grpc_request', { request: patchedRequest }); + await invokeCmd('cmd_update_grpc_request', { request: patchedRequest }); }, onMutate: async ({ id, update }) => { const request = await getGrpcRequest(id); diff --git a/src-web/hooks/useUpdateAnyHttpRequest.ts b/src-web/hooks/useUpdateAnyHttpRequest.ts index 32ced9ea..2a25fa69 100644 --- a/src-web/hooks/useUpdateAnyHttpRequest.ts +++ b/src-web/hooks/useUpdateAnyHttpRequest.ts @@ -1,7 +1,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { HttpRequest } from '../lib/models'; import { getHttpRequest } from '../lib/store'; +import { invokeCmd } from '../lib/tauri'; import { httpRequestsQueryKey } from './useHttpRequests'; export function useUpdateAnyHttpRequest() { @@ -20,7 +20,7 @@ export function useUpdateAnyHttpRequest() { const patchedRequest = typeof update === 'function' ? update(request) : { ...request, ...update }; - await invoke('cmd_update_http_request', { request: patchedRequest }); + await invokeCmd('cmd_update_http_request', { request: patchedRequest }); }, onMutate: async ({ id, update }) => { const request = await getHttpRequest(id); diff --git a/src-web/hooks/useUpdateCookieJar.ts b/src-web/hooks/useUpdateCookieJar.ts index 32282d03..b93de842 100644 --- a/src-web/hooks/useUpdateCookieJar.ts +++ b/src-web/hooks/useUpdateCookieJar.ts @@ -1,7 +1,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { CookieJar } from '../lib/models'; import { getCookieJar } from '../lib/store'; +import { invokeCmd } from '../lib/tauri'; import { cookieJarsQueryKey } from './useCookieJars'; export function useUpdateCookieJar(id: string | null) { @@ -15,7 +15,7 @@ export function useUpdateCookieJar(id: string | null) { const newCookieJar = typeof v === 'function' ? v(cookieJar) : { ...cookieJar, ...v }; console.log('NEW COOKIE JAR', newCookieJar.cookies.length); - await invoke('cmd_update_cookie_jar', { cookieJar: newCookieJar }); + await invokeCmd('cmd_update_cookie_jar', { cookieJar: newCookieJar }); }, onMutate: async (v) => { const cookieJar = await getCookieJar(id); diff --git a/src-web/hooks/useUpdateEnvironment.ts b/src-web/hooks/useUpdateEnvironment.ts index b9a055ee..d75886e2 100644 --- a/src-web/hooks/useUpdateEnvironment.ts +++ b/src-web/hooks/useUpdateEnvironment.ts @@ -1,7 +1,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { Environment } from '../lib/models'; import { getEnvironment } from '../lib/store'; +import { invokeCmd } from '../lib/tauri'; import { environmentsQueryKey } from './useEnvironments'; export function useUpdateEnvironment(id: string | null) { @@ -14,7 +14,7 @@ export function useUpdateEnvironment(id: string | null) { } const newEnvironment = typeof v === 'function' ? v(environment) : { ...environment, ...v }; - await invoke('cmd_update_environment', { environment: newEnvironment }); + await invokeCmd('cmd_update_environment', { environment: newEnvironment }); }, onMutate: async (v) => { const environment = await getEnvironment(id); diff --git a/src-web/hooks/useUpdateSettings.ts b/src-web/hooks/useUpdateSettings.ts index f4063055..ba81d197 100644 --- a/src-web/hooks/useUpdateSettings.ts +++ b/src-web/hooks/useUpdateSettings.ts @@ -1,6 +1,6 @@ import { useMutation } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { Settings } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; import { useSettings } from './useSettings'; export function useUpdateSettings() { @@ -10,7 +10,7 @@ export function useUpdateSettings() { mutationFn: async (patch) => { if (settings == null) return; const newSettings: Settings = { ...settings, ...patch }; - await invoke('cmd_update_settings', { settings: newSettings }); + await invokeCmd('cmd_update_settings', { settings: newSettings }); }, }); } diff --git a/src-web/hooks/useUpdateWorkspace.ts b/src-web/hooks/useUpdateWorkspace.ts index b1c299fe..cf2d6697 100644 --- a/src-web/hooks/useUpdateWorkspace.ts +++ b/src-web/hooks/useUpdateWorkspace.ts @@ -1,7 +1,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { Workspace } from '../lib/models'; import { getWorkspace } from '../lib/store'; +import { invokeCmd } from '../lib/tauri'; import { workspacesQueryKey } from './useWorkspaces'; export function useUpdateWorkspace(id: string | null) { @@ -14,7 +14,7 @@ export function useUpdateWorkspace(id: string | null) { } const newWorkspace = typeof v === 'function' ? v(workspace) : { ...workspace, ...v }; - await invoke('cmd_update_workspace', { workspace: newWorkspace }); + await invokeCmd('cmd_update_workspace', { workspace: newWorkspace }); }, onMutate: async (v) => { const workspace = await getWorkspace(id); diff --git a/src-web/hooks/useVariables.ts b/src-web/hooks/useVariables.ts deleted file mode 100644 index c661114d..00000000 --- a/src-web/hooks/useVariables.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { useQuery } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; -import type { EnvironmentVariable } from '../lib/models'; - -export function variablesQueryKey({ environmentId }: { environmentId: string }) { - return ['variables', { environmentId }]; -} - -export function useVariables({ environmentId }: { environmentId: string }) { - return ( - useQuery({ - queryKey: variablesQueryKey({ environmentId }), - queryFn: async () => { - return (await invoke('cmd_list_variables', { environmentId })) as EnvironmentVariable[]; - }, - }).data ?? [] - ); -} diff --git a/src-web/hooks/useWorkspaces.ts b/src-web/hooks/useWorkspaces.ts index 13fddddf..e02a86d8 100644 --- a/src-web/hooks/useWorkspaces.ts +++ b/src-web/hooks/useWorkspaces.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; -import { invoke } from '@tauri-apps/api/core'; import type { Workspace } from '../lib/models'; +import { invokeCmd } from '../lib/tauri'; // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/ban-types export function workspacesQueryKey(_?: {}) { @@ -12,7 +12,7 @@ export function useWorkspaces() { useQuery({ queryKey: workspacesQueryKey(), queryFn: async () => { - const workspaces = await invoke('cmd_list_workspaces'); + const workspaces = await invokeCmd('cmd_list_workspaces'); return workspaces as Workspace[]; }, }).data ?? [] diff --git a/src-web/lib/analytics.ts b/src-web/lib/analytics.ts index 3c2b10ed..e8e831cd 100644 --- a/src-web/lib/analytics.ts +++ b/src-web/lib/analytics.ts @@ -1,4 +1,4 @@ -import { invoke } from '@tauri-apps/api/core'; +import { invokeCmd } from './tauri'; export type TrackResource = | 'appearance' @@ -37,7 +37,7 @@ export function trackEvent( action: TrackAction, attributes: Record = {}, ) { - invoke('cmd_track_event', { + invokeCmd('cmd_track_event', { resource: resource, action, attributes, diff --git a/src-web/lib/keyValueStore.ts b/src-web/lib/keyValueStore.ts index 51245fa9..411967de 100644 --- a/src-web/lib/keyValueStore.ts +++ b/src-web/lib/keyValueStore.ts @@ -1,5 +1,5 @@ -import { invoke } from '@tauri-apps/api/core'; import type { KeyValue } from './models'; +import { invokeCmd } from './tauri'; export async function setKeyValue({ namespace = 'global', @@ -10,7 +10,7 @@ export async function setKeyValue({ key: string | string[]; value: T; }): Promise { - await invoke('cmd_set_key_value', { + await invokeCmd('cmd_set_key_value', { namespace, key: buildKeyValueKey(key), value: JSON.stringify(value), @@ -26,7 +26,7 @@ export async function getKeyValue({ key: string | string[]; fallback: T; }) { - const kv = (await invoke('cmd_get_key_value', { + const kv = (await invokeCmd('cmd_get_key_value', { namespace, key: buildKeyValueKey(key), })) as KeyValue | null; diff --git a/src-web/lib/sendEphemeralRequest.ts b/src-web/lib/sendEphemeralRequest.ts index 530ce19b..5751f414 100644 --- a/src-web/lib/sendEphemeralRequest.ts +++ b/src-web/lib/sendEphemeralRequest.ts @@ -1,5 +1,5 @@ -import { invoke } from '@tauri-apps/api/core'; import type { HttpRequest, HttpResponse } from './models'; +import { invokeCmd } from './tauri'; export async function sendEphemeralRequest( request: HttpRequest, @@ -7,5 +7,5 @@ export async function sendEphemeralRequest( ): Promise { // Remove some things that we don't want to associate const newRequest = { ...request }; - return invoke('cmd_send_ephemeral_request', { request: newRequest, environmentId }); + return invokeCmd('cmd_send_ephemeral_request', { request: newRequest, environmentId }); } diff --git a/src-web/lib/store.ts b/src-web/lib/store.ts index 5a08f1aa..e19550a8 100644 --- a/src-web/lib/store.ts +++ b/src-web/lib/store.ts @@ -1,4 +1,3 @@ -import { invoke } from '@tauri-apps/api/core'; import type { CookieJar, Environment, @@ -8,14 +7,15 @@ import type { Settings, Workspace, } from './models'; +import { invokeCmd } from './tauri'; export async function getSettings(): Promise { - return invoke('cmd_get_settings', {}); + return invokeCmd('cmd_get_settings', {}); } export async function getGrpcRequest(id: string | null): Promise { if (id === null) return null; - const request: GrpcRequest = (await invoke('cmd_get_grpc_request', { id })) ?? null; + const request: GrpcRequest = (await invokeCmd('cmd_get_grpc_request', { id })) ?? null; if (request == null) { return null; } @@ -24,7 +24,7 @@ export async function getGrpcRequest(id: string | null): Promise { if (id === null) return null; - const request: HttpRequest = (await invoke('cmd_get_http_request', { id })) ?? null; + const request: HttpRequest = (await invokeCmd('cmd_get_http_request', { id })) ?? null; if (request == null) { return null; } @@ -33,7 +33,7 @@ export async function getHttpRequest(id: string | null): Promise { if (id === null) return null; - const environment: Environment = (await invoke('cmd_get_environment', { id })) ?? null; + const environment: Environment = (await invokeCmd('cmd_get_environment', { id })) ?? null; if (environment == null) { return null; } @@ -42,7 +42,7 @@ export async function getEnvironment(id: string | null): Promise { if (id === null) return null; - const folder: Folder = (await invoke('cmd_get_folder', { id })) ?? null; + const folder: Folder = (await invokeCmd('cmd_get_folder', { id })) ?? null; if (folder == null) { return null; } @@ -51,7 +51,7 @@ export async function getFolder(id: string | null): Promise { export async function getWorkspace(id: string | null): Promise { if (id === null) return null; - const workspace: Workspace = (await invoke('cmd_get_workspace', { id })) ?? null; + const workspace: Workspace = (await invokeCmd('cmd_get_workspace', { id })) ?? null; if (workspace == null) { return null; } @@ -60,7 +60,7 @@ export async function getWorkspace(id: string | null): Promise export async function getCookieJar(id: string | null): Promise { if (id === null) return null; - const cookieJar: CookieJar = (await invoke('cmd_get_cookie_jar', { id })) ?? null; + const cookieJar: CookieJar = (await invokeCmd('cmd_get_cookie_jar', { id })) ?? null; if (cookieJar == null) { return null; } diff --git a/src-web/lib/tauri.ts b/src-web/lib/tauri.ts new file mode 100644 index 00000000..942637e2 --- /dev/null +++ b/src-web/lib/tauri.ts @@ -0,0 +1,70 @@ +import type { InvokeArgs } from '@tauri-apps/api/core'; +import { invoke } from '@tauri-apps/api/core'; + +type TauriCmd = + | 'cmd_check_for_updates' + | 'cmd_create_cookie_jar' + | 'cmd_create_environment' + | 'cmd_create_folder' + | 'cmd_create_grpc_request' + | 'cmd_create_http_request' + | 'cmd_create_workspace' + | 'cmd_curl_to_request' + | 'cmd_delete_all_grpc_connections' + | 'cmd_delete_all_http_responses' + | 'cmd_delete_cookie_jar' + | 'cmd_delete_environment' + | 'cmd_delete_folder' + | 'cmd_delete_grpc_connection' + | 'cmd_delete_grpc_request' + | 'cmd_delete_http_request' + | 'cmd_delete_http_response' + | 'cmd_delete_workspace' + | 'cmd_duplicate_grpc_request' + | 'cmd_duplicate_http_request' + | 'cmd_export_data' + | 'cmd_filter_response' + | 'cmd_get_cookie_jar' + | 'cmd_get_environment' + | 'cmd_get_folder' + | 'cmd_get_grpc_request' + | 'cmd_get_http_request' + | 'cmd_get_key_value' + | 'cmd_get_settings' + | 'cmd_get_workspace' + | 'cmd_grpc_go' + | 'cmd_grpc_reflect' + | 'cmd_import_data' + | 'cmd_list_cookie_jars' + | 'cmd_list_environments' + | 'cmd_list_folders' + | 'cmd_list_grpc_connections' + | 'cmd_list_grpc_events' + | 'cmd_list_grpc_requests' + | 'cmd_list_http_requests' + | 'cmd_list_http_responses' + | 'cmd_list_workspaces' + | 'cmd_metadata' + | 'cmd_new_nested_window' + | 'cmd_new_window' + | 'cmd_request_to_curl' + | 'cmd_dismiss_notification' + | 'cmd_save_response' + | 'cmd_send_ephemeral_request' + | 'cmd_send_http_request' + | 'cmd_set_key_value' + | 'cmd_set_update_mode' + | 'cmd_track_event' + | 'cmd_update_cookie_jar' + | 'cmd_update_environment' + | 'cmd_update_folder' + | 'cmd_update_grpc_request' + | 'cmd_update_http_request' + | 'cmd_update_settings' + | 'cmd_update_workspace' + | 'cmd_write_file_dev'; + +export async function invokeCmd(cmd: TauriCmd, args?: InvokeArgs): Promise { + // console.log('RUN COMMAND', cmd, args); + return invoke(cmd, args); +} diff --git a/src-web/main.tsx b/src-web/main.tsx index ce1bcf0a..b2e4351a 100644 --- a/src-web/main.tsx +++ b/src-web/main.tsx @@ -2,10 +2,10 @@ import { getCurrent } from '@tauri-apps/api/webviewWindow'; import { type } from '@tauri-apps/plugin-os'; import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; +import { pdfjs } from 'react-pdf'; import { attachConsole } from 'tauri-plugin-log-api'; import { App } from './components/App'; import './main.css'; -import { pdfjs } from 'react-pdf'; pdfjs.GlobalWorkerOptions.workerSrc = new URL( 'pdfjs-dist/build/pdf.worker.min.mjs',