From 79a09f831650499f51111d6bfa382c045e495682 Mon Sep 17 00:00:00 2001 From: cliffhall Date: Wed, 30 Apr 2025 17:09:22 -0400 Subject: [PATCH 1/2] Consolidate hooks * Hooks are in multiple places in the codebase and some camelCase, some snake-case. This PR relocates them all to the lib/hooks folder and normalizes camelCase naming. Settled on src/client/lib/hooks for the location since most of them were already there. - Refactor/move useTheme.ts from client/src/lib to client/src/lib/hooks - Refactor/move useToast.ts from client/src/hooks/ to client/src/lib/hooks/useToast.ts - Removed client/src/hooks --- client/src/components/JsonView.tsx | 2 +- client/src/components/OAuthCallback.tsx | 2 +- client/src/components/SamplingRequest.tsx | 2 +- client/src/components/Sidebar.tsx | 2 +- client/src/components/__tests__/Sidebar.test.tsx | 2 +- client/src/components/ui/toaster.tsx | 2 +- client/src/lib/hooks/__tests__/useConnection.test.tsx | 2 +- client/src/lib/hooks/useConnection.ts | 2 +- client/src/lib/{ => hooks}/useTheme.ts | 0 client/src/{hooks/use-toast.ts => lib/hooks/useToast.ts} | 0 10 files changed, 8 insertions(+), 8 deletions(-) rename client/src/lib/{ => hooks}/useTheme.ts (100%) rename client/src/{hooks/use-toast.ts => lib/hooks/useToast.ts} (100%) diff --git a/client/src/components/JsonView.tsx b/client/src/components/JsonView.tsx index bd7ef64..e9ef0d2 100644 --- a/client/src/components/JsonView.tsx +++ b/client/src/components/JsonView.tsx @@ -3,7 +3,7 @@ import type { JsonValue } from "@/utils/jsonUtils"; import clsx from "clsx"; import { Copy, CheckCheck } from "lucide-react"; import { Button } from "@/components/ui/button"; -import { useToast } from "@/hooks/use-toast"; +import { useToast } from "@/lib/hooks/useToast"; import { getDataType, tryParseJson } from "@/utils/jsonUtils"; interface JsonViewProps { diff --git a/client/src/components/OAuthCallback.tsx b/client/src/components/OAuthCallback.tsx index 6bfa8a3..ccfd6d9 100644 --- a/client/src/components/OAuthCallback.tsx +++ b/client/src/components/OAuthCallback.tsx @@ -2,7 +2,7 @@ import { useEffect, useRef } from "react"; import { InspectorOAuthClientProvider } from "../lib/auth"; import { SESSION_KEYS } from "../lib/constants"; import { auth } from "@modelcontextprotocol/sdk/client/auth.js"; -import { useToast } from "@/hooks/use-toast.ts"; +import { useToast } from "@/lib/hooks/useToast"; import { generateOAuthErrorDescription, parseOAuthCallbackParams, diff --git a/client/src/components/SamplingRequest.tsx b/client/src/components/SamplingRequest.tsx index 2fc22d9..0e6f365 100644 --- a/client/src/components/SamplingRequest.tsx +++ b/client/src/components/SamplingRequest.tsx @@ -7,7 +7,7 @@ import { } from "@modelcontextprotocol/sdk/types.js"; import { PendingRequest } from "./SamplingTab"; import DynamicJsonForm from "./DynamicJsonForm"; -import { useToast } from "@/hooks/use-toast"; +import { useToast } from "@/lib/hooks/useToast"; import { JsonSchemaType, JsonValue } from "@/utils/jsonUtils"; export type SamplingRequestProps = { diff --git a/client/src/components/Sidebar.tsx b/client/src/components/Sidebar.tsx index bc6af52..6c95daa 100644 --- a/client/src/components/Sidebar.tsx +++ b/client/src/components/Sidebar.tsx @@ -29,7 +29,7 @@ import { } from "@modelcontextprotocol/sdk/types.js"; import { InspectorConfig } from "@/lib/configurationTypes"; import { ConnectionStatus } from "@/lib/constants"; -import useTheme from "../lib/useTheme"; +import useTheme from "../lib/hooks/useTheme"; import { version } from "../../../package.json"; import { Tooltip, diff --git a/client/src/components/__tests__/Sidebar.test.tsx b/client/src/components/__tests__/Sidebar.test.tsx index 980dc01..df4ed64 100644 --- a/client/src/components/__tests__/Sidebar.test.tsx +++ b/client/src/components/__tests__/Sidebar.test.tsx @@ -7,7 +7,7 @@ import { InspectorConfig } from "@/lib/configurationTypes"; import { TooltipProvider } from "@/components/ui/tooltip"; // Mock theme hook -jest.mock("../../lib/useTheme", () => ({ +jest.mock("../../lib/hooks/useTheme", () => ({ __esModule: true, default: () => ["light", jest.fn()], })); diff --git a/client/src/components/ui/toaster.tsx b/client/src/components/ui/toaster.tsx index 5887f08..1c1b267 100644 --- a/client/src/components/ui/toaster.tsx +++ b/client/src/components/ui/toaster.tsx @@ -1,4 +1,4 @@ -import { useToast } from "@/hooks/use-toast"; +import { useToast } from "@/lib/hooks/useToast"; import { Toast, ToastClose, diff --git a/client/src/lib/hooks/__tests__/useConnection.test.tsx b/client/src/lib/hooks/__tests__/useConnection.test.tsx index e191d6c..c6700dc 100644 --- a/client/src/lib/hooks/__tests__/useConnection.test.tsx +++ b/client/src/lib/hooks/__tests__/useConnection.test.tsx @@ -37,7 +37,7 @@ jest.mock("@modelcontextprotocol/sdk/client/auth.js", () => ({ })); // Mock the toast hook -jest.mock("@/hooks/use-toast", () => ({ +jest.mock("@/lib/hooks/useToast", () => ({ useToast: () => ({ toast: jest.fn(), }), diff --git a/client/src/lib/hooks/useConnection.ts b/client/src/lib/hooks/useConnection.ts index 27bc11a..57efc63 100644 --- a/client/src/lib/hooks/useConnection.ts +++ b/client/src/lib/hooks/useConnection.ts @@ -27,7 +27,7 @@ import { } from "@modelcontextprotocol/sdk/types.js"; import { RequestOptions } from "@modelcontextprotocol/sdk/shared/protocol.js"; import { useState } from "react"; -import { useToast } from "@/hooks/use-toast"; +import { useToast } from "@/lib/hooks/useToast"; import { z } from "zod"; import { ConnectionStatus } from "../constants"; import { Notification, StdErrNotificationSchema } from "../notificationTypes"; diff --git a/client/src/lib/useTheme.ts b/client/src/lib/hooks/useTheme.ts similarity index 100% rename from client/src/lib/useTheme.ts rename to client/src/lib/hooks/useTheme.ts diff --git a/client/src/hooks/use-toast.ts b/client/src/lib/hooks/useToast.ts similarity index 100% rename from client/src/hooks/use-toast.ts rename to client/src/lib/hooks/useToast.ts From 59cc89dbe96914c8517b32ae3c708d8785c14407 Mon Sep 17 00:00:00 2001 From: cliffhall Date: Wed, 30 Apr 2025 17:31:58 -0400 Subject: [PATCH 2/2] Fix the inspector caching problem * I've noticed that on a new version of the inspector, I have to go to the browser's devtools panel and clear site data then reload the page. * The assets are hashed and immutable, so caching should be allowed for them * The index.html file is the problem, because if cached, it will point to old assets, and therefore needs to have caching turned forf * This PR adds appropriate headers to the index.html and assets that are served. --- client/bin/client.js | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/client/bin/client.js b/client/bin/client.js index d30cc70..7179e19 100755 --- a/client/bin/client.js +++ b/client/bin/client.js @@ -9,10 +9,34 @@ const __dirname = dirname(fileURLToPath(import.meta.url)); const distPath = join(__dirname, "../dist"); const server = http.createServer((request, response) => { - return handler(request, response, { + const handlerOptions = { public: distPath, rewrites: [{ source: "/**", destination: "/index.html" }], - }); + headers: [ + { + // Ensure index.html is never cached + source: "index.html", + headers: [ + { + key: "Cache-Control", + value: "no-cache, no-store, max-age=0", + }, + ], + }, + { + // Allow long-term caching for hashed assets + source: "assets/**", + headers: [ + { + key: "Cache-Control", + value: "public, max-age=31536000, immutable", + }, + ], + }, + ], + }; + + return handler(request, response, handlerOptions); }); const port = process.env.PORT || 6274;