tarasglek / chatcraft.org

Developer-oriented ChatGPT clone
https://chatcraft.org/
MIT License
148 stars 26 forks source link

Liberate our backend database from browser #311

Open tarasglek opened 6 months ago

tarasglek commented 6 months ago

It's cool to not have server-side infra..but it also kinda sucks to have a different copy of chatcraft history on every device. We should abstract our backend so it can be implemented locally or via some sql backend like turso or neon or supabase.

tarasglek commented 6 months ago

design i like would be to support a simple get/post api where you pass conversation history as a yaml list.

then we could have a gist backend, a s3 backend or a custom database backend that does template expansion executes custom hooks, etc

flow would look like passing a url and some auth token to chatcraft. it would first download the convo... and then on every db persist it would POST it.

a more complicated version of this would support multiple conversations, conversation search, etc

tarasglek commented 6 months ago

we could similarly store saved system prompts this way

humphd commented 5 months ago

To do this, we'd need to extract our IndexedDB/Dexie code and create an adapter for pluggable backends. I'm not sure what the interface for this would be exactly, but here's roughly how it works right now.

Our app is driven by React Router, which talks to the db, either directly or via classes that sit on top of it. For example, when you load a chat by its URL:

https://github.com/tarasglek/chatcraft.org/blob/6d575abc6071b2d3c4cbe6464a4e90e3fb83b08f/src/router.tsx#L62-L77

It will do a find() that eventually talks to the db here:

https://github.com/tarasglek/chatcraft.org/blob/main/src/lib/ChatCraftChat.ts#L237-L251

So we'd have to find all these db.* calls and figure out a more generic CRUD style API that we can put in front of the actual Dexie calls. This would then allow us to use S3, Neon, Supabase, etc. and hide the details behind this more generic data adapter interface.

We kind of do this already for shared chats, which we load as JSON from an API call to CloudFlare:

https://github.com/tarasglek/chatcraft.org/blob/6d575abc6071b2d3c4cbe6464a4e90e3fb83b08f/src/router.tsx#L124-L142

A bunch of the UI components are directly tied to Dexie at the moment via a hook that watches for live changes to the data store (e.g., if you modify something in one tab or component, it will cause a re-render in another). Making that work for remote data stores that don't have events would involve some re-architecting of the front-end to load the data once at the router level and pass it down via data context to all the components on the page vs. having them each work directly with the data in the db.

humphd commented 5 months ago

https://neon.tech/blog/api-cf-drizzle-neon is one interesting approach for an alternate backend.

humphd commented 5 months ago

https://blog.cloudflare.com/langchain-support-for-workers-ai-vectorize-and-d1/ points to some interesting approaches here. For example: using D1 for a chat database.