From 3574cf7c4ef7ac3cb0ff8ed35fd6105ac7d6d33d Mon Sep 17 00:00:00 2001 From: Aasif Khan Date: Fri, 25 Oct 2024 15:03:18 +0530 Subject: [PATCH 1/5] integrate cleanup time from playground-mono --- .../components/Playground/TerminalUI.tsx | 20 ++++++++++++++----- .../playground-web/components/Shell/Shell.tsx | 2 +- .../components/Shell/hooks/useShell.tsx | 4 +++- .../shared/utils/commonUtils.ts | 5 +++-- apps/playground-web/types/index.d.ts | 2 +- 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/apps/playground-web/components/Playground/TerminalUI.tsx b/apps/playground-web/components/Playground/TerminalUI.tsx index a9217b2..9c3d6c5 100644 --- a/apps/playground-web/components/Playground/TerminalUI.tsx +++ b/apps/playground-web/components/Playground/TerminalUI.tsx @@ -6,8 +6,10 @@ import { useState } from 'react'; import Tooltip from '../Overlays/Tooltip'; export function TerminalUI({ initialCommandsLeft = 1000 }) { const [commandsLeft, setCommandsLeft] = useState(initialCommandsLeft); - const handleCommandExecuted = (commands: number) => { + const [cleanupTimeLeft, setCleanupTimeLeft] = useState(15 * 60); + const handleCommandExecuted = (commands: number, cleanup: number) => { setCommandsLeft(commands); + setCleanupTimeLeft(cleanup); }; return ( @@ -27,13 +29,21 @@ export function TerminalUI({ initialCommandsLeft = 1000 }) { - + ); } -function TerminalCounter({ commandsLeft }: { commandsLeft: number }) { - const { timeLeft } = useTimer(15 * 60); +function TerminalCounter({ + commandsLeft, + cleanupTimeLeft, +}: { + commandsLeft: number; + cleanupTimeLeft: number; +}) { return (
@@ -42,7 +52,7 @@ function TerminalCounter({ commandsLeft }: { commandsLeft: number }) { className="flex items-center justify-between border border-gray-400 text-sm bg-transparent p-3 rounded-lg" data-testid="cleanup-timer" > - Cleanup in: {formatTime(timeLeft)} mins + Cleanup in: {formatTime(cleanupTimeLeft)} mins
diff --git a/apps/playground-web/components/Shell/Shell.tsx b/apps/playground-web/components/Shell/Shell.tsx index 643a9a3..81b7de5 100644 --- a/apps/playground-web/components/Shell/Shell.tsx +++ b/apps/playground-web/components/Shell/Shell.tsx @@ -5,7 +5,7 @@ import { useShell } from './hooks/useShell'; interface ShellProps { - onCommandExecuted: (commandsLeft: number) => void; + onCommandExecuted: (commandsLeft: number, cleanupTimeLeft: number) => void; } export default function Shell({ onCommandExecuted }: ShellProps) { diff --git a/apps/playground-web/components/Shell/hooks/useShell.tsx b/apps/playground-web/components/Shell/hooks/useShell.tsx index 5da2699..9c46973 100644 --- a/apps/playground-web/components/Shell/hooks/useShell.tsx +++ b/apps/playground-web/components/Shell/hooks/useShell.tsx @@ -5,7 +5,9 @@ import { useState, useEffect, useRef, KeyboardEvent, ChangeEvent } from 'react'; import { handleCommand } from '@/shared/utils/shellUtils'; import blocklistedCommands from '@/shared/utils/blocklist'; -export const useShell = (onCommandExecuted: (commandsLeft: number) => void) => { +export const useShell = ( + onCommandExecuted: (commandsLeft: number, cleanupTimeLeft: number) => void, +) => { // states const [command, setCommand] = useState(''); const [output, setOutput] = useState([]); diff --git a/apps/playground-web/shared/utils/commonUtils.ts b/apps/playground-web/shared/utils/commonUtils.ts index beaa013..c0e4efd 100644 --- a/apps/playground-web/shared/utils/commonUtils.ts +++ b/apps/playground-web/shared/utils/commonUtils.ts @@ -13,7 +13,7 @@ interface HandleResultProps { }; newOutput: string; setOutput: (prevOutput: any) => any; // Adjust type as necessary - onCommandExecuted: (commandsLeft: number) => void; // Allow undefined + onCommandExecuted: (commandsLeft: number, cleanupTimeLeft: number) => void; // Allow undefined } export const handleResult = ({ @@ -37,5 +37,6 @@ export const handleResult = ({ } const commandsLeft = Number(result.headers['x-ratelimit-remaining']); - onCommandExecuted(commandsLeft); + const cleanupTimeLeft = Number(result.headers['x-next-cleanup-time']); + onCommandExecuted(commandsLeft, cleanupTimeLeft); }; diff --git a/apps/playground-web/types/index.d.ts b/apps/playground-web/types/index.d.ts index cd03372..93a2a35 100644 --- a/apps/playground-web/types/index.d.ts +++ b/apps/playground-web/types/index.d.ts @@ -3,5 +3,5 @@ import * as React from 'react'; export interface CommandHandler { command: string; setOutput: React.Dispatch>; - onCommandExecuted: (commandsLeft: number) => void; + onCommandExecuted: (commandsLeft: number, cleanupTimeLeft: number) => void; } From 24884e2da8e48493107eb3dee93e3a3e2de21d4f Mon Sep 17 00:00:00 2001 From: Aasif Khan Date: Tue, 26 Nov 2024 05:02:04 -0800 Subject: [PATCH 2/5] testing --- .../components/Playground/TerminalUI.tsx | 30 ++++++++++-- apps/playground-web/lib/api.ts | 47 +++++++++++++++---- apps/playground-web/lib/healthResponse.ts | 3 ++ apps/playground-web/lib/monoSchema.ts | 13 ----- apps/playground-web/lib/schemas.ts | 20 ++++++++ apps/playground-web/services/webServices.ts | 12 ++++- tooling/eslint-config/package.json | 6 +-- 7 files changed, 101 insertions(+), 30 deletions(-) create mode 100644 apps/playground-web/lib/healthResponse.ts delete mode 100644 apps/playground-web/lib/monoSchema.ts create mode 100644 apps/playground-web/lib/schemas.ts diff --git a/apps/playground-web/components/Playground/TerminalUI.tsx b/apps/playground-web/components/Playground/TerminalUI.tsx index d279b79..4982597 100644 --- a/apps/playground-web/components/Playground/TerminalUI.tsx +++ b/apps/playground-web/components/Playground/TerminalUI.tsx @@ -1,11 +1,32 @@ import { Dice1, Dice3, Dice5, Info } from 'lucide-react'; import Shell from '../Shell/Shell'; import { formatTime } from '@/shared/utils/commonUtils'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; + import Tooltip from '../Overlays/Tooltip'; -export function TerminalUI({ initialCommandsLeft = 1000 }) { - const [commandsLeft, setCommandsLeft] = useState(initialCommandsLeft); - const [cleanupTimeLeft, setCleanupTimeLeft] = useState(15 * 60); +import { fetchHealthCheck } from '@/lib/api'; + +export function TerminalUI() { + + const [commandsLeft, setCommandsLeft] = useState(null); + const [cleanupTimeLeft, setCleanupTimeLeft] = useState(null); + + useEffect(() => { + const initializeHealthCheck = async () => { + try { + const { commandsLeft, cleanupTimeLeft } = await fetchHealthCheck(); + setCommandsLeft(commandsLeft); + setCleanupTimeLeft(cleanupTimeLeft); + } catch (error) { + console.error('Error initializing health check:', error); + setCommandsLeft(1000); // Fallback value + setCleanupTimeLeft(15 * 60); // Fallback value + } + }; + + initializeHealthCheck(); + }, []); + const handleCommandExecuted = (commands: number, cleanup: number) => { setCommandsLeft(commands); if (cleanup !== -1) { @@ -78,3 +99,4 @@ function TerminalCounter({ ); } + diff --git a/apps/playground-web/lib/api.ts b/apps/playground-web/lib/api.ts index 3a6e916..9936e62 100644 --- a/apps/playground-web/lib/api.ts +++ b/apps/playground-web/lib/api.ts @@ -12,17 +12,48 @@ export const executeShellCommandOnServer = async ( try { const response = await WebService.post(cmdExecURL, cmdOptions); - // Check if the response contains data or if it's an error response - if (response?.body?.data) { - return response; - } else if (response?.body?.error) { - return response; - } else { - throw new Error('Unexpected response structure'); - } + // Type guard to check if the body is MonoResponse + if ('data' in response.body) { + const parsedResponse = response.body as MonoResponse; + return {headers: response.headers, body: parsedResponse}; // MonoResponse + } else { + throw new Error('Unexpected response structure'); + } + + + // // Check if the response contains data or if it's an error response + // if (response?.body?.data) { + // return response; + // } else if (response?.body?.error) { + // return response; + // } else { + // throw new Error('Unexpected response structure'); + // } } catch (error) { // Propagate the error from the backend exactly as it is console.error('Error executing command:', error); throw new Error(`${error}`); } }; + + +// Fetch health check data from the server +export const fetchHealthCheck = async (): Promise<{ commandsLeft: number; cleanupTimeLeft: number }> => { + const healthCheckURL = `/health`; + + try { + const response = await WebService.get(healthCheckURL); + + if (response?.headers) { + const commandsLeft = parseInt(response.headers['X-Commands-Left'] || '1000', 10); + const cleanupTimeLeft = parseInt(response.headers['X-Next-Cleanup-Time'] || `${15 * 60}`, 10); + + return { commandsLeft, cleanupTimeLeft }; + } else { + throw new Error('Unexpected response structure: missing headers'); + } + } catch (error) { + console.error('Error fetching health check data:', error); + throw new Error(`${error}`); + } +}; diff --git a/apps/playground-web/lib/healthResponse.ts b/apps/playground-web/lib/healthResponse.ts new file mode 100644 index 0000000..138ac18 --- /dev/null +++ b/apps/playground-web/lib/healthResponse.ts @@ -0,0 +1,3 @@ +export interface HealthResponse { + message: string | null; +} \ No newline at end of file diff --git a/apps/playground-web/lib/monoSchema.ts b/apps/playground-web/lib/monoSchema.ts deleted file mode 100644 index 16651e1..0000000 --- a/apps/playground-web/lib/monoSchema.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { z } from 'zod'; - -const BodySchema = z.object({ - data: z.string(), -}); - -// Define the schema for an error response -const ErrorSchema = z.object({ - error: z.string(), -}); - -// Combine the schemas -export const MonoSchema = z.union([BodySchema, ErrorSchema]); diff --git a/apps/playground-web/lib/schemas.ts b/apps/playground-web/lib/schemas.ts new file mode 100644 index 0000000..e5f6a56 --- /dev/null +++ b/apps/playground-web/lib/schemas.ts @@ -0,0 +1,20 @@ +import { z } from 'zod'; + +// Schema for normal API responses +const BodySchema = z.object({ + data: z.string(), +}); + +// Define the schema for an error response +const ErrorSchema = z.object({ + error: z.string(), +}); + +// Schema for /health endpoint responses +export const HealthSchema = z.object({ + message: z.string(), +}); + +// Combined schema for normal responses +export const MonoSchema = z.union([BodySchema, ErrorSchema, HealthSchema]); + diff --git a/apps/playground-web/services/webServices.ts b/apps/playground-web/services/webServices.ts index 63c7461..65831da 100644 --- a/apps/playground-web/services/webServices.ts +++ b/apps/playground-web/services/webServices.ts @@ -1,6 +1,8 @@ -import { MonoSchema } from '@/lib/monoSchema'; +import { MonoSchema, } from '@/lib/schemas'; +import { z } from 'zod'; import { MonoResponse } from '@/lib/monoResponse'; +import { HealthResponse } from '@/lib//healthResponse'; let PLAYGROUND_MONO_URL = process.env.NEXT_PUBLIC_PLAYGROUND_MONO_URL; @@ -30,7 +32,7 @@ export const WebService = { headers: HeadersType, ): Promise<{ headers: { [key: string]: string }; - body: MonoResponse; + body: MonoResponse | HealthResponse; }> => { const options: RequestOptions = { method, @@ -69,6 +71,11 @@ export const WebService = { headers: headers, body: { data: parsedBody?.data?.data, error: null }, }; + } else if('message' in parsedBody.data) { + return { + headers: headers, + body: { message: parsedBody?.data?.message }, + }; } else { return { headers: headers, @@ -98,4 +105,5 @@ export const WebService = { post: (url: string, data: any, headers: HeadersType = {}) => { return WebService.request(url, 'POST', data, headers); }, + }; diff --git a/tooling/eslint-config/package.json b/tooling/eslint-config/package.json index c53bbfb..39e8164 100644 --- a/tooling/eslint-config/package.json +++ b/tooling/eslint-config/package.json @@ -8,12 +8,12 @@ "react-internal.js" ], "devDependencies": { + "@typescript-eslint/eslint-plugin": "^7.1.0", + "@typescript-eslint/parser": "^7.1.0", "@vercel/style-guide": "^5.2.0", - "eslint-config-turbo": "^2.0.0", "eslint-config-prettier": "^9.1.0", + "eslint-config-turbo": "^2.0.0", "eslint-plugin-only-warn": "^1.1.0", - "@typescript-eslint/parser": "^7.1.0", - "@typescript-eslint/eslint-plugin": "^7.1.0", "typescript": "^5.3.3" } } From 3e5a24c7ddaadc554531a7bbb2e59cdbb8da1f57 Mon Sep 17 00:00:00 2001 From: Aasif Khan Date: Wed, 27 Nov 2024 14:36:25 +0530 Subject: [PATCH 3/5] fix --- apps/playground-web/lib/api.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/playground-web/lib/api.ts b/apps/playground-web/lib/api.ts index 9936e62..44a978c 100644 --- a/apps/playground-web/lib/api.ts +++ b/apps/playground-web/lib/api.ts @@ -45,8 +45,8 @@ export const fetchHealthCheck = async (): Promise<{ commandsLeft: number; cleanu const response = await WebService.get(healthCheckURL); if (response?.headers) { - const commandsLeft = parseInt(response.headers['X-Commands-Left'] || '1000', 10); - const cleanupTimeLeft = parseInt(response.headers['X-Next-Cleanup-Time'] || `${15 * 60}`, 10); + const commandsLeft = parseInt(response?.headers['x-commands-left'] || '1000', 10); + const cleanupTimeLeft = parseInt(response?.headers['x-next-cleanup-time'] || `${15 * 60}`, 10); return { commandsLeft, cleanupTimeLeft }; } else { From 28d1330ce17a76ba721bbfa95e8fa4938eead897 Mon Sep 17 00:00:00 2001 From: Aasif Khan Date: Wed, 27 Nov 2024 14:44:24 +0530 Subject: [PATCH 4/5] refactor --- apps/playground-web/lib/api.ts | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/apps/playground-web/lib/api.ts b/apps/playground-web/lib/api.ts index 44a978c..f23fa7a 100644 --- a/apps/playground-web/lib/api.ts +++ b/apps/playground-web/lib/api.ts @@ -11,24 +11,16 @@ export const executeShellCommandOnServer = async ( try { const response = await WebService.post(cmdExecURL, cmdOptions); - // Type guard to check if the body is MonoResponse if ('data' in response.body) { - const parsedResponse = response.body as MonoResponse; - return {headers: response.headers, body: parsedResponse}; // MonoResponse + const body = response?.body as MonoResponse | undefined; + if (body?.data || body?.error) { + return { headers: response.headers, body }; + } + throw new Error('Unexpected response structure'); } else { throw new Error('Unexpected response structure'); } - - - // // Check if the response contains data or if it's an error response - // if (response?.body?.data) { - // return response; - // } else if (response?.body?.error) { - // return response; - // } else { - // throw new Error('Unexpected response structure'); - // } } catch (error) { // Propagate the error from the backend exactly as it is console.error('Error executing command:', error); From 26539f3c2d256d6b5bd00beb0b76711441d7c928 Mon Sep 17 00:00:00 2001 From: Aasif Khan Date: Thu, 12 Dec 2024 18:38:02 +0530 Subject: [PATCH 5/5] change header name --- apps/playground-web/lib/api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/playground-web/lib/api.ts b/apps/playground-web/lib/api.ts index f23fa7a..d4caac9 100644 --- a/apps/playground-web/lib/api.ts +++ b/apps/playground-web/lib/api.ts @@ -37,7 +37,7 @@ export const fetchHealthCheck = async (): Promise<{ commandsLeft: number; cleanu const response = await WebService.get(healthCheckURL); if (response?.headers) { - const commandsLeft = parseInt(response?.headers['x-commands-left'] || '1000', 10); + const commandsLeft = parseInt(response?.headers['x-ratelimit-remaining'] || '1000', 10); const cleanupTimeLeft = parseInt(response?.headers['x-next-cleanup-time'] || `${15 * 60}`, 10); return { commandsLeft, cleanupTimeLeft };