@myatthirikhin/chat-supabase
v0.1.0
Published
Supabase chat backend for @myatthirikhin/chat-core — Postgres schema, RLS, Realtime and Storage included.
Readme
@myatthirikhin/chat-supabase
A chat backend on Postgres, RLS, Realtime and Storage — the adapter and the schema.
pnpm add @myatthirikhin/chat-core @myatthirikhin/chat-supabase @supabase/supabase-jsThen apply the SQL. → SETUP.md — installing the package is half the job; the other half is a database.
import { ChatClient } from '@myatthirikhin/chat-core';
import { createSupabaseChatProvider } from '@myatthirikhin/chat-supabase';
const chat = new ChatClient({ provider: createSupabaseChatProvider(supabase) });
await chat.connect({ id: userId, name: 'Ana' });No tokenProvider: the Supabase session already in your client is the credential. There is no
token endpoint to deploy and no secret to rotate — the main practical difference from Stream and
Sendbird.
What ships here
| | |
|---|---|
| src/ | the IMessagingProvider implementation |
| sql/ | three migrations: schema + RLS + RPCs, Realtime, Storage |
| functions/push-fanout/ | an Edge Function that pushes through Expo's service |
Design notes
- Keyset pagination on
(conversation_id, id desc)— neverOFFSET, which is O(offset) and wrong under the concurrent inserts chat has by definition. - Read state is a monotonic watermark, not a receipts table. Receipts cost
messages × membersrows to buy a per-message timestamp no chat UI displays. - Soft delete only. A real
DELETEemits a Realtime event whose old-record payload is not RLS-filtered — a security decision, not a style one. - Three Realtime channels per client, forever, regardless of conversation count. Realtime caps channels at 100 per connection, so one subscription per conversation breaks at 100 conversations.
- One
SECURITY DEFINERhelper breaks the members↔messages RLS recursion (42P17).
Scaling
The first wall is concurrent connections (500 on Pro with the spend cap on), not throughput.
Then messages/sec, which counts after fan-out. postgres_changes doesn't get faster on a bigger
instance; past ~3,000 concurrent subscribers, switch to broadcast-from-database — the SQL is at the
bottom of sql/0002_chat_realtime.sql.
License
MIT
