Skip to content

Commit 4084384

Browse files
committed
feat(inspector): make inspector compatible with new architecture (#2920)
1 parent 4d11ba5 commit 4084384

12 files changed

+204
-154
lines changed

frontend/src/app/connect.tsx

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { faNodeJs, faReact, Icon } from "@rivet-gg/icons";
2+
import { useSearch } from "@tanstack/react-router";
3+
import type { ComponentProps, Ref } from "react";
4+
import {
5+
Button,
6+
Card,
7+
CardContent,
8+
CardHeader,
9+
CardTitle,
10+
DocsSheet,
11+
} from "@/components";
12+
import { ConnectionForm } from "@/components/connection-form";
13+
import { docsLinks } from "@/content/data";
14+
15+
export function Connect({
16+
onSubmit,
17+
formRef,
18+
}: {
19+
formRef?: Ref<HTMLFormElement>;
20+
onSubmit: ComponentProps<typeof ConnectionForm>["onSubmit"];
21+
}) {
22+
const search = useSearch({ from: "/_context" });
23+
return (
24+
<>
25+
<Card className="sm:w-96 w-full mb-6">
26+
<CardHeader>
27+
<CardTitle>Getting Started</CardTitle>
28+
</CardHeader>
29+
<CardContent>
30+
<p>Get started with one of our quick start guides:</p>
31+
<div className="flex-1 flex flex-col gap-2 mt-4">
32+
<div className="flex flex-row justify-stretch items-center gap-2">
33+
<DocsSheet
34+
path={docsLinks.gettingStarted.node}
35+
title="Node.js & Bun Quickstart"
36+
>
37+
<Button
38+
className="flex-1"
39+
variant="outline"
40+
startIcon={<Icon icon={faNodeJs} />}
41+
>
42+
Node.js & Bun
43+
</Button>
44+
</DocsSheet>
45+
<DocsSheet
46+
path={docsLinks.gettingStarted.react}
47+
title="React Quickstart"
48+
>
49+
<Button
50+
className="flex-1"
51+
variant="outline"
52+
startIcon={<Icon icon={faReact} />}
53+
>
54+
React
55+
</Button>
56+
</DocsSheet>
57+
</div>
58+
</div>
59+
</CardContent>
60+
</Card>
61+
62+
<Card className="sm:w-96">
63+
<CardHeader>
64+
<CardTitle>Connect to Project</CardTitle>
65+
</CardHeader>
66+
<CardContent>
67+
<p className="mb-4">
68+
Connect to your RivetKit project by entering the URL and
69+
access token.
70+
</p>
71+
72+
<ConnectionForm
73+
ref={formRef}
74+
defaultValues={{
75+
username: search.u || "http://localhost:6420",
76+
token: search.t || "",
77+
}}
78+
onSubmit={onSubmit}
79+
/>
80+
</CardContent>
81+
</Card>
82+
</>
83+
);
84+
}

frontend/src/components/actors/actors-actor-details.tsx

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { ActorStopButton } from "./actor-stop-button";
2222
import { ActorsSidebarToggleButton } from "./actors-sidebar-toggle-button";
2323
import { useActorsView } from "./actors-view-context-provider";
2424
import { ActorConsole } from "./console/actor-console";
25-
import { GuardConnectableInspector } from "./guard-connectable-inspector";
25+
import { GuardConnectableInspector, useInspectorGuard } from "./guard-connectable-inspector";
2626
import { useManager } from "./manager-context";
2727
import { ActorFeature, type ActorId } from "./queries";
2828
import { ActorWorkerContextProvider } from "./worker/actor-worker-context";
@@ -48,29 +48,27 @@ export const ActorsActorDetails = memo(
4848
const supportsConsole = features.includes(ActorFeature.Console);
4949

5050
return (
51+
52+
<GuardConnectableInspector actorId={actorId}>
5153
<ActorDetailsSettingsProvider>
5254
<div className="flex flex-col h-full flex-1">
5355
<ActorTabs
5456
features={features}
5557
actorId={actorId}
5658
tab={tab}
5759
onTabChange={onTabChange}
58-
// onExportLogs={onExportLogs}
59-
// isExportingLogs={isExportingLogs}
6060
/>
6161

6262
{supportsConsole ? (
6363
<ActorWorkerContextProvider
6464
actorId={actorId}
65-
// notifyOnReconnect={features?.includes(
66-
// ActorFeature.InspectReconnectNotification,
67-
// )}
6865
>
6966
<ActorConsole actorId={actorId} />
7067
</ActorWorkerContextProvider>
7168
) : null}
7269
</div>
7370
</ActorDetailsSettingsProvider>
71+
</GuardConnectableInspector>
7472
);
7573
},
7674
);
@@ -121,6 +119,8 @@ export function ActorTabs({
121119
const defaultTab = supportsState ? "state" : "logs";
122120
const value = disabled ? undefined : tab || defaultTab;
123121

122+
const guardContent = useInspectorGuard();
123+
124124
return (
125125
<Tabs
126126
value={value}
@@ -220,9 +220,7 @@ export function ActorTabs({
220220
className="min-h-0 flex-1 mt-0 h-full"
221221
>
222222
<Suspense fallback={<ActorLogsTab.Skeleton />}>
223-
<GuardConnectableInspector actorId={actorId}>
224-
<ActorLogsTab actorId={actorId} />
225-
</GuardConnectableInspector>
223+
{guardContent || <ActorLogsTab actorId={actorId} />}
226224
</Suspense>
227225
</TabsContent>
228226
) : null}
@@ -239,49 +237,39 @@ export function ActorTabs({
239237
value="connections"
240238
className="min-h-0 flex-1 mt-0"
241239
>
242-
<GuardConnectableInspector actorId={actorId}>
243-
<ActorConnectionsTab actorId={actorId} />
244-
</GuardConnectableInspector>
240+
{guardContent ||<ActorConnectionsTab actorId={actorId} />}
245241
</TabsContent>
246242
) : null}
247243
{supportsEvents ? (
248244
<TabsContent
249245
value="events"
250246
className="min-h-0 flex-1 mt-0"
251247
>
252-
<GuardConnectableInspector actorId={actorId}>
253-
<ActorEventsTab actorId={actorId} />
254-
</GuardConnectableInspector>
248+
{guardContent || <ActorEventsTab actorId={actorId} />}
255249
</TabsContent>
256250
) : null}
257251
{supportsDatabase ? (
258252
<TabsContent
259253
value="database"
260254
className="min-h-0 min-w-0 flex-1 mt-0 h-full"
261255
>
262-
<GuardConnectableInspector actorId={actorId}>
263-
<ActorDatabaseTab actorId={actorId} />
264-
</GuardConnectableInspector>
256+
{guardContent || <ActorDatabaseTab actorId={actorId} />}
265257
</TabsContent>
266258
) : null}
267259
{supportsState ? (
268260
<TabsContent
269261
value="state"
270262
className="min-h-0 flex-1 mt-0"
271263
>
272-
<GuardConnectableInspector actorId={actorId}>
273-
<ActorStateTab actorId={actorId} />
274-
</GuardConnectableInspector>
264+
{guardContent || <ActorStateTab actorId={actorId} />}
275265
</TabsContent>
276266
) : null}
277267
{supportsMetrics ? (
278268
<TabsContent
279269
value="metrics"
280270
className="min-h-0 flex-1 mt-0 h-full"
281271
>
282-
<GuardConnectableInspector actorId={actorId}>
283-
<ActorMetricsTab actorId={actorId} />
284-
</GuardConnectableInspector>
272+
{guardContent || <ActorMetricsTab actorId={actorId} />}
285273
</TabsContent>
286274
) : null}
287275
</>

frontend/src/components/actors/console/actor-console.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ export function ActorConsole({ actorId }: ActorConsoleProps) {
2121
const status = useActorWorkerStatus();
2222
const managerQueries = useManager();
2323
const actorQueries = useActor();
24-
const { data: destroyedAt } = useQuery(
25-
managerQueries.actorDestroyedAtQueryOptions(actorId),
24+
const { data: { destroyedAt, sleepingAt } = {} } = useQuery(
25+
managerQueries.actorWorkerQueryOptions(actorId),
2626
);
2727
const { isSuccess, isError, isLoading } = useQuery(
2828
actorQueries.actorPingQueryOptions(actorId, {
@@ -31,7 +31,8 @@ export function ActorConsole({ actorId }: ActorConsoleProps) {
3131
}),
3232
);
3333

34-
const isBlocked = status.type !== "ready" || !isSuccess || !!destroyedAt;
34+
const isBlocked =
35+
status.type !== "ready" || !isSuccess || !!destroyedAt || !!sleepingAt;
3536

3637
const combinedStatus = isError
3738
? "error"

frontend/src/components/actors/guard-connectable-inspector.tsx

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
11
import { faPowerOff, faSpinnerThird, Icon } from "@rivet-gg/icons";
22
import { useMutation, useQuery, useSuspenseQuery } from "@tanstack/react-query";
33
import { useMatch } from "@tanstack/react-router";
4-
import { type ReactNode, useMemo } from "react";
4+
import { createContext, type ReactNode, useContext, useMemo } from "react";
55
import { useInspectorCredentials } from "@/app/credentials-context";
6-
import { createEngineActorContext } from "@/queries/actor-engine";
76
import { createInspectorActorContext } from "@/queries/actor-inspector";
87
import {
98
type NamespaceNameId,
109
runnerByNameQueryOptions,
1110
} from "@/queries/manager-engine";
1211
import { DiscreteCopyButton } from "../copy-area";
12+
import { getConfig } from "../lib/config";
1313
import { Button } from "../ui/button";
1414
import { useFiltersValue } from "./actor-filters-context";
1515
import { ActorProvider } from "./actor-queries-context";
1616
import { Info } from "./actor-state-tab";
1717
import { useManager } from "./manager-context";
1818
import type { ActorId } from "./queries";
1919

20+
const InspectorGuardContext = createContext<ReactNode | null>(null);
21+
22+
export const useInspectorGuard = () => useContext(InspectorGuardContext);
23+
2024
interface GuardConnectableInspectorProps {
2125
actorId: ActorId;
2226
children: ReactNode;
@@ -35,31 +39,56 @@ export function GuardConnectableInspector({
3539
});
3640

3741
if (destroyedAt) {
38-
return <Info>Unavailable for inactive Actors.</Info>;
42+
return (
43+
<InspectorGuardContext.Provider
44+
value={<Info>Unavailable for inactive Actors.</Info>}
45+
>
46+
{children}
47+
</InspectorGuardContext.Provider>
48+
);
3949
}
4050

4151
if (sleepingAt) {
4252
if (filters.wakeOnSelect?.value?.[0] === "1") {
4353
return (
44-
<Info>
45-
<AutoWakeUpActor actorId={actorId} />
46-
</Info>
54+
<InspectorGuardContext.Provider
55+
value={
56+
<Info>
57+
<AutoWakeUpActor actorId={actorId} />
58+
</Info>
59+
}
60+
>
61+
{children}
62+
</InspectorGuardContext.Provider>
4763
);
4864
}
4965
return (
50-
<Info>
51-
<p>Unavailable for sleeping Actors.</p>
52-
<WakeUpActorButton actorId={actorId} />
53-
</Info>
66+
<InspectorGuardContext.Provider
67+
value={
68+
<Info>
69+
<p>Unavailable for sleeping Actors.</p>
70+
<WakeUpActorButton actorId={actorId} />
71+
</Info>
72+
}
73+
>
74+
{children}
75+
</InspectorGuardContext.Provider>
5476
);
5577
}
5678

5779
if (pendingAllocationAt && !startedAt) {
5880
return (
59-
<Info>
60-
Cannot start Actor, runners are out of capacity. Add more
61-
runners to run the Actor or increase runner capacity.
62-
</Info>
81+
<InspectorGuardContext.Provider
82+
value={
83+
<Info>
84+
Cannot start Actor, runners are out of capacity. Add
85+
more runners to run the Actor or increase runner
86+
capacity.
87+
</Info>
88+
}
89+
>
90+
{children}
91+
</InspectorGuardContext.Provider>
6392
);
6493
}
6594

@@ -81,14 +110,7 @@ function ActorContextProvider(props: {
81110
);
82111
}
83112

84-
function ActorInspectorProvider({
85-
actorId,
86-
children,
87-
}: {
88-
actorId: ActorId;
89-
children: ReactNode;
90-
}) {
91-
const { data } = useSuspenseQuery(useManager().actorQueryOptions(actorId));
113+
function ActorInspectorProvider({ children }: { children: ReactNode }) {
92114
const { credentials } = useInspectorCredentials();
93115

94116
if (!credentials?.url || !credentials?.token) {
@@ -98,9 +120,8 @@ function ActorInspectorProvider({
98120
const actorContext = useMemo(() => {
99121
return createInspectorActorContext({
100122
...credentials,
101-
name: data.name || "",
102123
});
103-
}, [credentials, data.name]);
124+
}, [credentials]);
104125

105126
return <ActorProvider value={actorContext}>{children}</ActorProvider>;
106127
}
@@ -133,7 +154,8 @@ function useActorEngineContext({ actorId }: { actorId: ActorId }) {
133154
const { actor, runner } = useActorRunner({ actorId });
134155

135156
const actorContext = useMemo(() => {
136-
return createEngineActorContext({
157+
return createInspectorActorContext({
158+
url: getConfig().apiUrl,
137159
token: (runner?.metadata?.inspectorToken as string) || "",
138160
});
139161
}, [runner?.metadata?.inspectorToken]);
@@ -152,7 +174,15 @@ function ActorEngineProvider({
152174

153175
if (!runner || !actor.runner) {
154176
return (
155-
<NoRunnerInfo runner={runner?.name || actor.runner || "unknown"} />
177+
<InspectorGuardContext.Provider
178+
value={
179+
<NoRunnerInfo
180+
runner={runner?.name || actor.runner || "unknown"}
181+
/>
182+
}
183+
>
184+
{children}
185+
</InspectorGuardContext.Provider>
156186
);
157187
}
158188

frontend/src/components/actors/manager-context.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ const defaultContext = {
296296
destroyedAt: data.destroyedAt
297297
? new Date(data.destroyedAt)
298298
: null,
299+
sleepingAt: data.sleepingAt ? new Date(data.sleepingAt) : null,
299300
startedAt: data.startedAt ? new Date(data.startedAt) : null,
300301
}),
301302
});

0 commit comments

Comments
 (0)