Skip to content

Commit

Permalink
supabase client is now a singleton
Browse files Browse the repository at this point in the history
  • Loading branch information
nerfZael committed Dec 28, 2023
1 parent 6bca38b commit 99a8279
Show file tree
Hide file tree
Showing 15 changed files with 187 additions and 115 deletions.
5 changes: 4 additions & 1 deletion apps/browser/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ import { useRouter } from "next/navigation";
import { useAtom } from "jotai";
import { v4 as uuid } from "uuid";
import { InMemoryFile } from "@nerfzael/memory-fs";
import { useSupabaseClient } from "@/lib/supabase/useSupabaseClient";

function Dojo({ params }: { params: { id?: string } }) {
const supabase = useSupabaseClient();
const [evoService, setEvoService] = useAtom(evoServiceAtom);
const [newGoalSubmitted, setNewGoalSubmitted] = useAtom(newGoalSubmittedAtom);
const [isChatLoading, setIsChatLoading] = useAtom(isChatLoadingAtom);
Expand All @@ -43,13 +45,14 @@ function Dojo({ params }: { params: { id?: string } }) {
const { data: chats, isLoading: isChatsLoading } = useChats();
const router = useRouter();
const { status: sessionStatus, data: sessionData } = useSession();
const isAuthenticated = sessionStatus === "authenticated";
const isAuthenticated = sessionStatus === "authenticated" && !!supabase;

const { mutateAsync: createChat } = useCreateChat();
const { mutateAsync: updateChatTitle } = useUpdateChatTitle();
const { logs, isConnected, isStarting, isRunning, handleStart, status } = useEvoService(
chatId,
isAuthenticated,
supabase
);

const workspaceUploadUpdate = useWorkspaceUploadUpdate();
Expand Down
17 changes: 10 additions & 7 deletions apps/browser/components/providers/Providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ import { Provider as JotaiProvider } from "jotai";
import ReactQueryProvider from "./ReactQueryProvider";
import { SessionProvider } from "next-auth/react";
import ToastProvider from "./ToastProvider";
import SupabaseClientProvider from "@/lib/supabase/SupabaseClientProvider";

export function Providers({ children }: { children: React.ReactNode }) {
return (
<SessionProvider>
<JotaiProvider>
<ToastProvider>
<ReactQueryProvider>
{children}
</ReactQueryProvider>
</ToastProvider>
</JotaiProvider>
<SupabaseClientProvider>
<JotaiProvider>
<ToastProvider>
<ReactQueryProvider>
{children}
</ReactQueryProvider>
</ToastProvider>
</JotaiProvider>
</SupabaseClientProvider>
</SessionProvider>
);
}
16 changes: 7 additions & 9 deletions apps/browser/lib/hooks/useEvoService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,21 @@ import { EvoThreadCallbacks, EvoThreadConfig } from "@/lib/services/evo/EvoThrea
import { useAddChatLog } from "@/lib/mutations/useAddChatLog";
import { useAddMessages } from "@/lib/mutations/useAddMessages";
import { useAddVariable } from "@/lib/mutations/useAddVariable";
import { useChats } from "@/lib/queries/useChats";
import { fetchChats, useChats } from "@/lib/queries/useChats";
import { SupabaseWorkspace } from "@/lib/supabase/SupabaseWorkspace";
import { useSupabaseClient } from "@/lib/supabase/useSupabaseClient";
import { useWorkspaceFilesUpdate } from "@/lib/hooks/useWorkspaceFilesUpdate";
import { useWorkspaceUploadUpdate } from "@/lib/hooks/useWorkspaceUploadUpdate";
import { ChatLog } from "@/components/Chat";
import { Workspace, InMemoryWorkspace } from "@evo-ninja/agent-utils";
import { ChatLogType, ChatMessage } from "@evo-ninja/agents";
import { useState, useEffect } from "react";
import { useAtom } from "jotai";
import { EvoSupabaseClient } from "../supabase/EvoSupabaseClient";

export const useEvoService = (
chatId: string | "<anon>" | undefined,
isAuthenticated: boolean,
supabase: EvoSupabaseClient | undefined
): {
logs: ChatLog[];
isConnected: boolean;
Expand All @@ -33,8 +34,6 @@ export const useEvoService = (
status: string | undefined;
handleStart: (goal: string) => Promise<void>;
} => {
const supabase = useSupabaseClient();

// Globals
const [evoService] = useAtom(evoServiceAtom);
const [allowTelemetry] = useAtom(allowTelemetryAtom);
Expand All @@ -56,9 +55,6 @@ export const useEvoService = (
const { mutateAsync: addMessages } = useAddMessages();
const { mutateAsync: addVariable } = useAddVariable();

// Queries
const { refetch: fetchChats } = useChats();

// Helpers
const workspaceFilesUpdate = useWorkspaceFilesUpdate();
const workspaceUploadUpdate = useWorkspaceUploadUpdate();
Expand Down Expand Up @@ -122,7 +118,7 @@ export const useEvoService = (
return [];
}

const { data: chats, error } = await fetchChats();
const { data: chats, error } = await fetchChats(supabase!);

if (error) {
console.error(error);
Expand All @@ -140,8 +136,10 @@ export const useEvoService = (
};

async function loadWorkspace(chatId: string): Promise<Workspace> {
// isAuthenticated is only true if there's a supabase instance
// so we can safely assume that it's not undefined
const workspace = isAuthenticated ?
new SupabaseWorkspace(chatId, supabase.storage) :
new SupabaseWorkspace(chatId, supabase!.storage) :
new InMemoryWorkspace();

await workspaceUploadUpdate(workspace);
Expand Down
12 changes: 7 additions & 5 deletions apps/browser/lib/mutations/useAddChatLog.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { useMutation, useQueryClient } from "@tanstack/react-query"
import { useSession } from "next-auth/react"
import { ChatLog } from "@/components/Chat"
import { Row } from "../supabase/types"
import { createSupabaseClient } from "../supabase/createSupabaseClient"
import { useSupabaseClient } from "../supabase/useSupabaseClient"

const mapChatLogToLogDTO = (
chatId: string,
Expand All @@ -17,15 +16,18 @@ const mapChatLogToLogDTO = (
}

export const useAddChatLog = () => {
const { data: session } = useSession()
const queryClient = useQueryClient()
const queryClient = useQueryClient();
const supabase = useSupabaseClient();

return useMutation({
mutationFn: async (args: {
chatId: string;
log: ChatLog;
}) => {
const supabase = createSupabaseClient(session?.supabaseAccessToken as string)
if (!supabase) {
throw new Error("Not authenticated");
}

const { error } = await supabase
.from("logs")
.insert(
Expand Down
12 changes: 7 additions & 5 deletions apps/browser/lib/mutations/useAddMessages.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { useMutation, useQueryClient } from "@tanstack/react-query"
import { useSession } from "next-auth/react"
import { ChatLogType, ChatMessage } from "@evo-ninja/agents"
import { Row } from "../supabase/types"
import { createSupabaseClient } from "../supabase/createSupabaseClient"
import { useSupabaseClient } from "../supabase/useSupabaseClient"

const mapChatMessageToMessageDTO = (
chatId: string,
Expand Down Expand Up @@ -64,16 +63,19 @@ const mapChatMessageToMessageDTO = (
}

export const useAddMessages = () => {
const { data: session } = useSession()
const queryClient = useQueryClient()
const queryClient = useQueryClient();
const supabase = useSupabaseClient();

return useMutation({
mutationFn: async (args: {
chatId: string;
messages: ChatMessage[];
type: ChatLogType;
}) => {
const supabase = createSupabaseClient(session?.supabaseAccessToken as string)
if (!supabase) {
throw new Error("Not authenticated");
}

const { error } = await supabase
.from("messages")
.insert(
Expand Down
12 changes: 7 additions & 5 deletions apps/browser/lib/mutations/useAddVariable.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useMutation, useQueryClient } from "@tanstack/react-query"
import { useSession } from "next-auth/react"
import { Row } from "../supabase/types"
import { createSupabaseClient } from "../supabase/createSupabaseClient"
import { useSupabaseClient } from "../supabase/useSupabaseClient"

const mapVariableToVariableDTO = (
chatId: string,
Expand All @@ -16,16 +15,19 @@ const mapVariableToVariableDTO = (
}

export const useAddVariable = () => {
const { data: session } = useSession()
const queryClient = useQueryClient()
const queryClient = useQueryClient();
const supabase = useSupabaseClient();

return useMutation({
mutationFn: async (args: {
chatId: string;
key: string;
value: string;
}) => {
const supabase = createSupabaseClient(session?.supabaseAccessToken as string)
if (!supabase) {
throw new Error("Not authenticated");
}

const { error } = await supabase
.from("variables")
.insert(
Expand Down
12 changes: 7 additions & 5 deletions apps/browser/lib/mutations/useCreateChat.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { createSupabaseClient } from "../supabase/createSupabaseClient"
import { Chat } from "@/lib/queries/useChats"
import { useMutation, useQueryClient } from "@tanstack/react-query"
import { useSession } from "next-auth/react"
import { useSupabaseClient } from "../supabase/useSupabaseClient";

export const useCreateChat = () => {
const { data: session } = useSession()
const queryClient = useQueryClient()
const queryClient = useQueryClient();
const supabase = useSupabaseClient();

return useMutation({
mutationFn: async (chatId: string) => {
const supabase = createSupabaseClient(session?.supabaseAccessToken as string)
if (!supabase) {
throw new Error("Not authenticated");
}

const { data, error } = await supabase
.from("chats")
.insert({
Expand Down
12 changes: 7 additions & 5 deletions apps/browser/lib/mutations/useDeleteChat.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { createSupabaseClient } from "../supabase/createSupabaseClient"
import { useMutation, useQueryClient } from "@tanstack/react-query"
import { useSession } from "next-auth/react"
import { useSupabaseClient } from "../supabase/useSupabaseClient";

export const useDeleteChat = () => {
const { data: session } = useSession()
const queryClient = useQueryClient()
const queryClient = useQueryClient();
const supabase = useSupabaseClient();

return useMutation({
mutationFn: async (chatId: string) => {
const supabase = createSupabaseClient(session?.supabaseAccessToken as string)
if (!supabase) {
throw new Error("Not authenticated");
}

const { error } = await supabase
.from("chats")
.delete()
Expand Down
12 changes: 6 additions & 6 deletions apps/browser/lib/mutations/useUpdateChatTitle.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { createSupabaseClient } from "../supabase/createSupabaseClient";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useSession } from "next-auth/react";
import { useSupabaseClient } from "../supabase/useSupabaseClient";

export const useUpdateChatTitle = () => {
const { data: session } = useSession();
const queryClient = useQueryClient();
const supabase = useSupabaseClient();

return useMutation({
mutationFn: async (args: { chatId: string; title: string }) => {
const supabase = createSupabaseClient(
session?.supabaseAccessToken as string
);
if (!supabase) {
throw new Error("Not authenticated");
}

const { error } = await supabase
.from("chats")
.update({ title: args.title })
Expand Down
83 changes: 53 additions & 30 deletions apps/browser/lib/queries/useChats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useSession } from "next-auth/react"
import { ChatMessage } from "@evo-ninja/agents"
import { ChatLog } from "@/components/Chat"
import { Json } from "../supabase/dbTypes"
import { createSupabaseClient } from "../supabase/createSupabaseClient"
import { useSupabaseClient } from "../supabase/useSupabaseClient"

export interface Chat {
id: string;
Expand Down Expand Up @@ -110,45 +110,68 @@ const mapChatDTOtoChat = (dto: ChatDTO): Chat => {
}
}

export const fetchChats = async (supabase: any): Promise<{
data: Chat[] | undefined,
error: Error | undefined
}> => {
const { data, error } = await supabase
.from('chats')
.select(`
id,
created_at,
logs(id, created_at, title, content, user),
variables(id, key, value),
title,
messages(
id,
created_at,
content,
name,
function_call,
tool_calls,
temporary,
role,
tool_call_id
)
`).order(
'created_at',
{ ascending: false }
)

if (error) {
return {
data: undefined,
error: error
}
}

return {
data: data.map(mapChatDTOtoChat),
error: undefined
};
}

export const useChats = () => {
const { data: session } = useSession()
const { data: session } = useSession();
const supabase = useSupabaseClient();

return useQuery({
queryKey: ['chats'],
enabled: !!session?.user?.email,
queryKey: ['chats', session?.user?.email, supabase],
enabled: !!session?.user?.email && !!supabase,
refetchOnMount: false,
queryFn: async () => {
const supabase = createSupabaseClient(session?.supabaseAccessToken as string)
const { data, error } = await supabase
.from('chats')
.select(`
id,
created_at,
logs(id, created_at, title, content, user),
variables(id, key, value),
title,
messages(
id,
created_at,
content,
name,
function_call,
tool_calls,
temporary,
role,
tool_call_id
)
`).order(
'created_at',
{ ascending: false }
)
if (!session?.user?.email || !supabase) {
throw new Error("Not authenticated")
}

const { data, error } = await fetchChats(supabase);

if (error) {
console.error(error)
throw new Error(error.message)
throw new Error(error.message);
}

return data.map(mapChatDTOtoChat)
return data;
}
})
}
Loading

0 comments on commit 99a8279

Please sign in to comment.