diff --git a/src-tauri/.sqlx/query-697afa2c3072b7b01676be53d5857066724fc23c94cd279d074253d5581b6f2c.json b/src-tauri/.sqlx/query-1821c2f60b9fa4514d58eb73b23e25ad683b80b9bd0c2944063190a0d0a19ee5.json similarity index 81% rename from src-tauri/.sqlx/query-697afa2c3072b7b01676be53d5857066724fc23c94cd279d074253d5581b6f2c.json rename to src-tauri/.sqlx/query-1821c2f60b9fa4514d58eb73b23e25ad683b80b9bd0c2944063190a0d0a19ee5.json index 42b6a01f..2c549a1a 100644 --- a/src-tauri/.sqlx/query-697afa2c3072b7b01676be53d5857066724fc23c94cd279d074253d5581b6f2c.json +++ b/src-tauri/.sqlx/query-1821c2f60b9fa4514d58eb73b23e25ad683b80b9bd0c2944063190a0d0a19ee5.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority,\n url, service, method, message, authentication_type,\n authentication AS \"authentication!: Json>\",\n proto_files AS \"proto_files!: sqlx::types::Json>\",\n metadata AS \"metadata!: sqlx::types::Json>\"\n FROM grpc_requests\n WHERE id = ?\n ", + "query": "\n SELECT\n id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority,\n url, service, method, message, authentication_type,\n authentication AS \"authentication!: Json>\",\n metadata AS \"metadata!: sqlx::types::Json>\"\n FROM grpc_requests\n WHERE workspace_id = ?\n ", "describe": { "columns": [ { @@ -73,14 +73,9 @@ "ordinal": 13, "type_info": "Text" }, - { - "name": "proto_files!: sqlx::types::Json>", - "ordinal": 14, - "type_info": "Text" - }, { "name": "metadata!: sqlx::types::Json>", - "ordinal": 15, + "ordinal": 14, "type_info": "Text" } ], @@ -102,9 +97,8 @@ false, true, false, - false, false ] }, - "hash": "697afa2c3072b7b01676be53d5857066724fc23c94cd279d074253d5581b6f2c" + "hash": "1821c2f60b9fa4514d58eb73b23e25ad683b80b9bd0c2944063190a0d0a19ee5" } diff --git a/src-tauri/.sqlx/query-38e8fd3b0959623322bf49cf6682a4ddeac667cf6e71b97bc7e122848ad1565f.json b/src-tauri/.sqlx/query-38e8fd3b0959623322bf49cf6682a4ddeac667cf6e71b97bc7e122848ad1565f.json deleted file mode 100644 index 0d196755..00000000 --- a/src-tauri/.sqlx/query-38e8fd3b0959623322bf49cf6682a4ddeac667cf6e71b97bc7e122848ad1565f.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO grpc_requests (\n id, name, workspace_id, folder_id, sort_priority, url, service, method, message,\n proto_files, authentication_type, authentication, metadata\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n name = excluded.name,\n folder_id = excluded.folder_id,\n sort_priority = excluded.sort_priority,\n url = excluded.url,\n service = excluded.service,\n method = excluded.method,\n message = excluded.message,\n proto_files = excluded.proto_files,\n authentication_type = excluded.authentication_type,\n authentication = excluded.authentication,\n metadata = excluded.metadata\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 13 - }, - "nullable": [] - }, - "hash": "38e8fd3b0959623322bf49cf6682a4ddeac667cf6e71b97bc7e122848ad1565f" -} diff --git a/src-tauri/.sqlx/query-467b87ad1209a4653b1dc8462d79236a655240c5b402fa9fd75c12ebd9bb6b86.json b/src-tauri/.sqlx/query-467b87ad1209a4653b1dc8462d79236a655240c5b402fa9fd75c12ebd9bb6b86.json new file mode 100644 index 00000000..f77a9243 --- /dev/null +++ b/src-tauri/.sqlx/query-467b87ad1209a4653b1dc8462d79236a655240c5b402fa9fd75c12ebd9bb6b86.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT INTO grpc_requests (\n id, name, workspace_id, folder_id, sort_priority, url, service, method, message,\n authentication_type, authentication, metadata\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n name = excluded.name,\n folder_id = excluded.folder_id,\n sort_priority = excluded.sort_priority,\n url = excluded.url,\n service = excluded.service,\n method = excluded.method,\n message = excluded.message,\n authentication_type = excluded.authentication_type,\n authentication = excluded.authentication,\n metadata = excluded.metadata\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 12 + }, + "nullable": [] + }, + "hash": "467b87ad1209a4653b1dc8462d79236a655240c5b402fa9fd75c12ebd9bb6b86" +} diff --git a/src-tauri/.sqlx/query-24a721700844cb0ea9c2585c4df796ec10188b559063a9093e432ae993154f31.json b/src-tauri/.sqlx/query-e1cdba43bd938772631263966a9bee263923c387f4864917f36a04043bec4857.json similarity index 80% rename from src-tauri/.sqlx/query-24a721700844cb0ea9c2585c4df796ec10188b559063a9093e432ae993154f31.json rename to src-tauri/.sqlx/query-e1cdba43bd938772631263966a9bee263923c387f4864917f36a04043bec4857.json index 663bbcbc..6d970900 100644 --- a/src-tauri/.sqlx/query-24a721700844cb0ea9c2585c4df796ec10188b559063a9093e432ae993154f31.json +++ b/src-tauri/.sqlx/query-e1cdba43bd938772631263966a9bee263923c387f4864917f36a04043bec4857.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority,\n url, service, method, message, authentication_type,\n authentication AS \"authentication!: Json>\",\n proto_files AS \"proto_files!: sqlx::types::Json>\",\n metadata AS \"metadata!: sqlx::types::Json>\"\n FROM grpc_requests\n WHERE workspace_id = ?\n ", + "query": "\n SELECT\n id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority,\n url, service, method, message, authentication_type,\n authentication AS \"authentication!: Json>\",\n metadata AS \"metadata!: sqlx::types::Json>\"\n FROM grpc_requests\n WHERE id = ?\n ", "describe": { "columns": [ { @@ -73,14 +73,9 @@ "ordinal": 13, "type_info": "Text" }, - { - "name": "proto_files!: sqlx::types::Json>", - "ordinal": 14, - "type_info": "Text" - }, { "name": "metadata!: sqlx::types::Json>", - "ordinal": 15, + "ordinal": 14, "type_info": "Text" } ], @@ -102,9 +97,8 @@ false, true, false, - false, false ] }, - "hash": "24a721700844cb0ea9c2585c4df796ec10188b559063a9093e432ae993154f31" + "hash": "e1cdba43bd938772631263966a9bee263923c387f4864917f36a04043bec4857" } diff --git a/src-tauri/migrations/20240203164833_grpc.sql b/src-tauri/migrations/20240203164833_grpc.sql index aa1494c0..d0ebe6af 100644 --- a/src-tauri/migrations/20240203164833_grpc.sql +++ b/src-tauri/migrations/20240203164833_grpc.sql @@ -17,7 +17,6 @@ CREATE TABLE grpc_requests service TEXT NULL, method TEXT NULL, message TEXT NOT NULL, - proto_files TEXT DEFAULT '[]' NOT NULL, authentication TEXT DEFAULT '{}' NOT NULL, authentication_type TEXT NULL, metadata TEXT DEFAULT '[]' NOT NULL diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 6f13ac4f..f5233d2a 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -98,6 +98,7 @@ async fn migrate_db(app_handle: AppHandle, db: &Mutex>) -> Result<( #[tauri::command] async fn cmd_grpc_reflect( request_id: &str, + proto_files: Vec, window: Window, grpc_handle: State<'_, Mutex>, ) -> Result, String> { @@ -105,15 +106,14 @@ async fn cmd_grpc_reflect( .await .map_err(|e| e.to_string())?; let uri = safe_uri(&req.url).map_err(|e| e.to_string())?; - if req.proto_files.0.len() > 0 { + if proto_files.len() > 0 { grpc_handle .lock() .await .services_from_files( &req.id, &uri, - req.proto_files - .0 + proto_files .iter() .map(|p| PathBuf::from_str(p).unwrap()) .collect(), @@ -132,6 +132,7 @@ async fn cmd_grpc_reflect( async fn cmd_grpc_go( request_id: &str, environment_id: Option<&str>, + proto_files: Vec, w: Window, grpc_handle: State<'_, Mutex>, ) -> Result { @@ -240,8 +241,7 @@ async fn cmd_grpc_go( .connect( &req.clone().id, uri, - req.proto_files - .0 + proto_files .iter() .map(|p| PathBuf::from_str(p).unwrap()) .collect(), diff --git a/src-tauri/src/models.rs b/src-tauri/src/models.rs index 3f92981c..39f6ca47 100644 --- a/src-tauri/src/models.rs +++ b/src-tauri/src/models.rs @@ -213,7 +213,6 @@ pub struct GrpcRequest { pub service: Option, pub method: Option, pub message: String, - pub proto_files: Json>, pub authentication_type: Option, pub authentication: Json>, pub metadata: Json>, @@ -525,9 +524,9 @@ pub async fn upsert_grpc_request( r#" INSERT INTO grpc_requests ( id, name, workspace_id, folder_id, sort_priority, url, service, method, message, - proto_files, authentication_type, authentication, metadata + authentication_type, authentication, metadata ) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT (id) DO UPDATE SET updated_at = CURRENT_TIMESTAMP, name = excluded.name, @@ -537,7 +536,6 @@ pub async fn upsert_grpc_request( service = excluded.service, method = excluded.method, message = excluded.message, - proto_files = excluded.proto_files, authentication_type = excluded.authentication_type, authentication = excluded.authentication, metadata = excluded.metadata @@ -551,7 +549,6 @@ pub async fn upsert_grpc_request( request.service, request.method, request.message, - request.proto_files, request.authentication_type, request.authentication, request.metadata, @@ -577,7 +574,6 @@ pub async fn get_grpc_request( id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority, url, service, method, message, authentication_type, authentication AS "authentication!: Json>", - proto_files AS "proto_files!: sqlx::types::Json>", metadata AS "metadata!: sqlx::types::Json>" FROM grpc_requests WHERE id = ? @@ -600,7 +596,6 @@ pub async fn list_grpc_requests( id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority, url, service, method, message, authentication_type, authentication AS "authentication!: Json>", - proto_files AS "proto_files!: sqlx::types::Json>", metadata AS "metadata!: sqlx::types::Json>" FROM grpc_requests WHERE workspace_id = ? diff --git a/src-web/components/GrpcConnectionLayout.tsx b/src-web/components/GrpcConnectionLayout.tsx index 11aee200..4ad494d8 100644 --- a/src-web/components/GrpcConnectionLayout.tsx +++ b/src-web/components/GrpcConnectionLayout.tsx @@ -5,6 +5,7 @@ import { useActiveRequest } from '../hooks/useActiveRequest'; import { useGrpc } from '../hooks/useGrpc'; import { useGrpcConnections } from '../hooks/useGrpcConnections'; import { useGrpcEvents } from '../hooks/useGrpcEvents'; +import { useGrpcProtoFiles } from '../hooks/useGrpcProtoFiles'; import { useUpdateGrpcRequest } from '../hooks/useUpdateGrpcRequest'; import { Banner } from './core/Banner'; import { HotKeyList } from './core/HotKeyList'; @@ -22,7 +23,9 @@ export function GrpcConnectionLayout({ style }: Props) { const connections = useGrpcConnections(activeRequest?.id ?? null); const activeConnection = connections[0] ?? null; const messages = useGrpcEvents(activeConnection?.id ?? null); - const grpc = useGrpc(activeRequest, activeConnection); + const protoFilesKv = useGrpcProtoFiles(activeRequest?.id ?? null); + const protoFiles = protoFilesKv.value ?? []; + const grpc = useGrpc(activeRequest, activeConnection, protoFiles); const services = grpc.reflect.data ?? null; useEffect(() => { @@ -79,6 +82,7 @@ export function GrpcConnectionLayout({ style }: Props) { diff --git a/src-web/components/GrpcEditor.tsx b/src-web/components/GrpcEditor.tsx index 6ac8617e..f3378487 100644 --- a/src-web/components/GrpcEditor.tsx +++ b/src-web/components/GrpcEditor.tsx @@ -21,6 +21,7 @@ type Props = Pick & { reflectionError?: string; reflectionLoading?: boolean; request: GrpcRequest; + protoFiles: string[]; }; export function GrpcEditor({ @@ -28,6 +29,7 @@ export function GrpcEditor({ reflectionError, reflectionLoading, request, + protoFiles, ...extraEditorProps }: Props) { const editorViewRef = useRef(null); @@ -149,9 +151,9 @@ export function GrpcEditor({ ? 'Select Proto Files' : reflectionError ? 'Server Error' - : request.protoFiles.length > 0 - ? count('File', request.protoFiles.length) - : services != null && request.protoFiles.length === 0 + : protoFiles.length > 0 + ? count('File', protoFiles.length) + : services != null && protoFiles.length === 0 ? 'Schema Detected' : 'Select Schema'} diff --git a/src-web/components/GrpcProtoSelection.tsx b/src-web/components/GrpcProtoSelection.tsx index e6c8dba9..27a783b2 100644 --- a/src-web/components/GrpcProtoSelection.tsx +++ b/src-web/components/GrpcProtoSelection.tsx @@ -1,7 +1,7 @@ import { open } from '@tauri-apps/api/dialog'; import { useGrpc } from '../hooks/useGrpc'; +import { useGrpcProtoFiles } from '../hooks/useGrpcProtoFiles'; import { useGrpcRequest } from '../hooks/useGrpcRequest'; -import { useUpdateGrpcRequest } from '../hooks/useUpdateGrpcRequest'; import { count } from '../lib/pluralize'; import { Banner } from './core/Banner'; import { Button } from './core/Button'; @@ -18,10 +18,11 @@ interface Props { export function GrpcProtoSelection({ requestId }: Props) { const request = useGrpcRequest(requestId); - const grpc = useGrpc(request, null); - const updateRequest = useUpdateGrpcRequest(request?.id ?? null); + const protoFilesKv = useGrpcProtoFiles(requestId); + const protoFiles = protoFilesKv.value ?? []; + const grpc = useGrpc(request, null, protoFiles); const services = grpc.reflect.data; - const serverReflection = request?.protoFiles.length === 0 && services != null; + const serverReflection = protoFiles.length === 0 && services != null; let reflectError = grpc.reflect.error ?? null; const reflectionUnimplemented = `${reflectError}`.match(/unimplemented/i); @@ -47,8 +48,8 @@ export function GrpcProtoSelection({ requestId }: Props) { filters: [{ name: 'Proto Files', extensions: ['proto'] }], }); if (files == null || typeof files === 'string') return; - const newFiles = files.filter((f) => !request.protoFiles.includes(f)); - await updateRequest.mutateAsync({ protoFiles: [...request.protoFiles, ...newFiles] }); + const newFiles = files.filter((f) => !protoFiles.includes(f)); + await protoFilesKv.set([...protoFiles, ...newFiles]); await grpc.reflect.refetch(); }} > @@ -99,7 +100,7 @@ export function GrpcProtoSelection({ requestId }: Props) { )} - {request.protoFiles.length > 0 && ( + {protoFiles.length > 0 && ( @@ -110,7 +111,7 @@ export function GrpcProtoSelection({ requestId }: Props) { - {request.protoFiles.map((f, i) => ( + {protoFiles.map((f, i) => (
{f.split('/').pop()} @@ -120,9 +121,7 @@ export function GrpcProtoSelection({ requestId }: Props) { icon="trash" className="ml-auto opacity-30 transition-opacity group-hover:opacity-100" onClick={async () => { - await updateRequest.mutateAsync({ - protoFiles: request.protoFiles.filter((p) => p !== f), - }); + await protoFilesKv.set(protoFiles.filter((p) => p !== f)); grpc.reflect.remove(); }} /> @@ -133,7 +132,7 @@ export function GrpcProtoSelection({ requestId }: Props) {
)} {reflectError && {reflectError}} - {reflectionUnimplemented && request.protoFiles.length === 0 && ( + {reflectionUnimplemented && protoFiles.length === 0 && ( {request.url} doesn't implement{' '} diff --git a/src-web/hooks/useGrpc.ts b/src-web/hooks/useGrpc.ts index 35db6967..7b284eb1 100644 --- a/src-web/hooks/useGrpc.ts +++ b/src-web/hooks/useGrpc.ts @@ -11,12 +11,16 @@ export interface ReflectResponseService { methods: { name: string; schema: string; serverStreaming: boolean; clientStreaming: boolean }[]; } -export function useGrpc(req: GrpcRequest | null, conn: GrpcConnection | null) { +export function useGrpc( + req: GrpcRequest | null, + conn: GrpcConnection | null, + protoFiles: string[], +) { const requestId = req?.id ?? 'n/a'; const environmentId = useActiveEnvironmentId(); const go = useMutation({ - mutationFn: async () => await invoke('cmd_grpc_go', { requestId, environmentId }), + mutationFn: async () => await invoke('cmd_grpc_go', { requestId, environmentId, protoFiles }), }); const send = useMutation({ @@ -35,13 +39,13 @@ export function useGrpc(req: GrpcRequest | null, conn: GrpcConnection | null) { }); const debouncedUrl = useDebouncedValue(req?.url ?? 'n/a', 1000); - const reflect = useQuery({ + const reflect = useQuery({ enabled: req != null, queryKey: ['grpc_reflect', req?.id ?? 'n/a', debouncedUrl], refetchOnWindowFocus: false, queryFn: async () => { return (await minPromiseMillis( - invoke('cmd_grpc_reflect', { requestId }), + invoke('cmd_grpc_reflect', { requestId, protoFiles }), 300, )) as ReflectResponseService[]; }, diff --git a/src-web/hooks/useGrpcProtoFiles.ts b/src-web/hooks/useGrpcProtoFiles.ts new file mode 100644 index 00000000..ef5949cc --- /dev/null +++ b/src-web/hooks/useGrpcProtoFiles.ts @@ -0,0 +1,10 @@ +import { NAMESPACE_GLOBAL } from '../lib/keyValueStore'; +import { useKeyValue } from './useKeyValue'; + +export function useGrpcProtoFiles(activeRequestId: string | null) { + return useKeyValue({ + namespace: NAMESPACE_GLOBAL, + key: ['proto_files', activeRequestId ?? 'n/a'], + defaultValue: [], + }); +} diff --git a/src-web/hooks/useUpdateMode.ts b/src-web/hooks/useUpdateMode.ts deleted file mode 100644 index 5fc8637e..00000000 --- a/src-web/hooks/useUpdateMode.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { NAMESPACE_APP } from '../lib/keyValueStore'; -import { useKeyValue } from './useKeyValue'; - -export function useUpdateMode() { - const kv = useKeyValue<'stable' | 'beta'>({ - namespace: NAMESPACE_APP, - key: 'update_mode', - defaultValue: 'stable', - }); - - return [kv.value, kv.set] as const; -} diff --git a/src-web/lib/keyValueStore.ts b/src-web/lib/keyValueStore.ts index 76269c62..a41f6db6 100644 --- a/src-web/lib/keyValueStore.ts +++ b/src-web/lib/keyValueStore.ts @@ -1,7 +1,6 @@ import { invoke } from '@tauri-apps/api'; import type { KeyValue } from './models'; -export const NAMESPACE_APP = 'app'; export const NAMESPACE_GLOBAL = 'global'; export const NAMESPACE_NO_SYNC = 'no_sync'; diff --git a/src-web/lib/models.ts b/src-web/lib/models.ts index c0d97d27..ae629641 100644 --- a/src-web/lib/models.ts +++ b/src-web/lib/models.ts @@ -121,7 +121,6 @@ export interface GrpcRequest extends BaseModel { service: string | null; method: string | null; message: string; - protoFiles: string[]; authentication: Record; authenticationType: string | null; metadata: GrpcMetadataEntry[];