generated from TBD54566975/tbd-project-template
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
39 changed files
with
1,437 additions
and
629 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,5 @@ | ||
import { Navigate, Route, Routes } from 'react-router-dom' | ||
import { ConsolePage } from './features/console/ConsolePage.tsx' | ||
import { DeploymentPage } from './features/deployments/DeploymentPage.tsx' | ||
import { DeploymentsPage } from './features/deployments/DeploymentsPage.tsx' | ||
import { TimelinePage } from './features/timeline/TimelinePage.tsx' | ||
import { VerbPage } from './features/verbs/VerbPage.tsx' | ||
import { Layout } from './layout/Layout.tsx' | ||
import { NotFoundPage } from './layout/NotFoundPage.tsx' | ||
import { AppProvider } from './providers/app-providers.tsx' | ||
|
||
export const App = () => { | ||
return ( | ||
<Routes> | ||
<Route path='/' element={<Layout />}> | ||
<Route path='/' element={<Navigate to='events' replace />} /> | ||
<Route path='events' element={<TimelinePage />} /> | ||
|
||
<Route path='deployments' element={<DeploymentsPage />} /> | ||
<Route path='deployments/:deploymentKey' element={<DeploymentPage />} /> | ||
<Route path='deployments/:deploymentKey/verbs/:verbName' element={<VerbPage />} /> | ||
<Route path='console' element={<ConsolePage />} /> | ||
</Route> | ||
<Route path='*' element={<NotFoundPage />} /> | ||
</Routes> | ||
) | ||
return <AppProvider /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { Code, ConnectError } from '@connectrpc/connect' | ||
import { useQuery, useQueryClient } from '@tanstack/react-query' | ||
import { useEffect } from 'react' | ||
import { useClient } from '../../hooks/use-client' | ||
import { ConsoleService } from '../../protos/xyz/block/ftl/v1/console/console_connect' | ||
import { useSchema } from '../schema/use-schema' | ||
|
||
const useModulesKey = 'modules' | ||
|
||
export const useModules = () => { | ||
const client = useClient(ConsoleService) | ||
const queryClient = useQueryClient() | ||
const { data: streamingData } = useSchema() | ||
|
||
useEffect(() => { | ||
if (streamingData) { | ||
queryClient.invalidateQueries({ | ||
queryKey: [useModulesKey], | ||
}) | ||
} | ||
}, [streamingData, queryClient]) | ||
|
||
const fetchModules = async (signal: AbortSignal) => { | ||
try { | ||
console.debug('fetching modules from FTL') | ||
const modules = await client.getModules({}, { signal }) | ||
return modules ?? [] | ||
} catch (error) { | ||
if (error instanceof ConnectError) { | ||
if (error.code !== Code.Canceled) { | ||
console.error('fetchModules - Connect error:', error) | ||
} | ||
} else { | ||
console.error('fetchModules:', error) | ||
} | ||
throw error | ||
} | ||
} | ||
|
||
return useQuery({ | ||
queryKey: [useModulesKey], | ||
queryFn: async ({ signal }) => fetchModules(signal), | ||
enabled: !!streamingData, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { Code, ConnectError } from '@connectrpc/connect' | ||
import { useQuery, useQueryClient } from '@tanstack/react-query' | ||
import { useClient } from '../../hooks/use-client.ts' | ||
import { useVisibility } from '../../hooks/use-visibility.ts' | ||
import { ControllerService } from '../../protos/xyz/block/ftl/v1/ftl_connect.ts' | ||
import { DeploymentChangeType, type PullSchemaResponse } from '../../protos/xyz/block/ftl/v1/ftl_pb.ts' | ||
|
||
const streamingSchemaKey = 'streamingSchema' | ||
|
||
export const useSchema = () => { | ||
const client = useClient(ControllerService) | ||
const queryClient = useQueryClient() | ||
const isVisible = useVisibility() | ||
|
||
const streamSchema = async (signal: AbortSignal) => { | ||
try { | ||
const schemaMap = new Map<string, PullSchemaResponse>() | ||
for await (const response of client.pullSchema({}, { signal })) { | ||
const moduleName = response.moduleName ?? '' | ||
console.log(`schema changed: ${DeploymentChangeType[response.changeType]} ${moduleName}`) | ||
switch (response.changeType) { | ||
case DeploymentChangeType.DEPLOYMENT_ADDED: | ||
schemaMap.set(moduleName, response) | ||
break | ||
case DeploymentChangeType.DEPLOYMENT_CHANGED: | ||
schemaMap.set(moduleName, response) | ||
break | ||
case DeploymentChangeType.DEPLOYMENT_REMOVED: | ||
schemaMap.delete(moduleName) | ||
} | ||
|
||
if (!response.more) { | ||
const schema = Array.from(schemaMap.values()).sort((a, b) => a.schema?.name?.localeCompare(b.schema?.name ?? '') ?? 0) | ||
queryClient.setQueryData([streamingSchemaKey], schema) | ||
} | ||
} | ||
} catch (error) { | ||
if (error instanceof ConnectError) { | ||
if (error.code !== Code.Canceled) { | ||
console.error('useSchema - streamSchema - Connect error:', error) | ||
} | ||
} else { | ||
console.error('useSchema - streamSchema:', error) | ||
} | ||
} | ||
} | ||
|
||
return useQuery({ | ||
queryKey: [streamingSchemaKey], | ||
queryFn: async ({ signal }) => streamSchema(signal), | ||
enabled: isVisible, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export * from './stream-verb-calls' | ||
export * from './timeline-filters' | ||
export * from './use-request-calls' | ||
export * from './use-timeline-calls' | ||
export * from './use-timeline' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { callFilter } from './timeline-filters.ts' | ||
import { useTimelineCalls } from './use-timeline-calls.ts' | ||
|
||
export const useStreamVerbCalls = (moduleName?: string, verbName?: string, enabled = true) => { | ||
return useTimelineCalls(true, [callFilter(moduleName || '', verbName)], enabled) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { requestKeysFilter } from './timeline-filters' | ||
import { useTimelineCalls } from './use-timeline-calls' | ||
|
||
export const useRequestCalls = (requestKey?: string) => { | ||
return useTimelineCalls(true, [requestKeysFilter([requestKey || ''])], !!requestKey) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { type CallEvent, EventType, type EventsQuery_Filter } from '../../protos/xyz/block/ftl/v1/console/console_pb.ts' | ||
import { eventTypesFilter } from './timeline-filters.ts' | ||
import { useTimeline } from './use-timeline.ts' | ||
|
||
export const useTimelineCalls = (isStreaming: boolean, filters: EventsQuery_Filter[], enabled = true) => { | ||
const allFilters = [...filters, eventTypesFilter([EventType.CALL])] | ||
const timelineQuery = useTimeline(isStreaming, allFilters, enabled) | ||
|
||
// Map the events to CallEvent for ease of use | ||
const data = timelineQuery.data?.map((event) => event.entry.value as CallEvent) || [] | ||
|
||
return { | ||
...timelineQuery, | ||
data, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { Code, ConnectError } from '@connectrpc/connect' | ||
import { useQuery, useQueryClient } from '@tanstack/react-query' | ||
import { useClient } from '../../hooks/use-client' | ||
import { useVisibility } from '../../hooks/use-visibility' | ||
import { ConsoleService } from '../../protos/xyz/block/ftl/v1/console/console_connect' | ||
import { type EventsQuery_Filter, EventsQuery_Order } from '../../protos/xyz/block/ftl/v1/console/console_pb' | ||
|
||
const timelineKey = 'timeline' | ||
const maxTimelineEntries = 1000 | ||
|
||
export const useTimeline = (isStreaming: boolean, filters: EventsQuery_Filter[], enabled = true) => { | ||
const client = useClient(ConsoleService) | ||
const queryClient = useQueryClient() | ||
const isVisible = useVisibility() | ||
|
||
const order = EventsQuery_Order.DESC | ||
const limit = isStreaming ? 200 : 1000 | ||
|
||
const queryKey = [timelineKey, isStreaming, filters, order, limit] | ||
|
||
const fetchTimeline = async ({ signal }: { signal: AbortSignal }) => { | ||
try { | ||
console.log('fetching timeline') | ||
const response = await client.getEvents({ filters, limit, order }, { signal }) | ||
return response.events | ||
} catch (error) { | ||
if (error instanceof ConnectError) { | ||
if (error.code === Code.Canceled) { | ||
return [] | ||
} | ||
} | ||
throw error | ||
} | ||
} | ||
|
||
const streamTimeline = async ({ signal }: { signal: AbortSignal }) => { | ||
try { | ||
console.log('streaming timeline') | ||
console.log('filters:', filters) | ||
for await (const response of client.streamEvents({ updateInterval: { seconds: BigInt(1) }, query: { limit, filters, order } }, { signal })) { | ||
if (response.events) { | ||
const prev = queryClient.getQueryData<Event[]>(queryKey) ?? [] | ||
const allEvents = [...response.events, ...prev].slice(0, maxTimelineEntries) | ||
queryClient.setQueryData(queryKey, allEvents) | ||
} | ||
} | ||
} catch (error) { | ||
if (error instanceof ConnectError) { | ||
if (error.code !== Code.Canceled) { | ||
console.error('Console service - streamEvents - Connect error:', error) | ||
} | ||
} else { | ||
console.error('Console service - streamEvents:', error) | ||
} | ||
} | ||
} | ||
|
||
return useQuery({ | ||
queryKey: queryKey, | ||
queryFn: async ({ signal }) => (isStreaming ? streamTimeline({ signal }) : fetchTimeline({ signal })), | ||
enabled: enabled && isVisible, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.