This commit is contained in:
2026-04-18 23:11:35 +02:00
commit f7cfd2a86e
196 changed files with 35538 additions and 0 deletions
+25
View File
@@ -0,0 +1,25 @@
// Postgres bytea <-> Uint8Array.
//
// PostgREST serializes bytea as a "\x<hex>" string in JSON. When inserting via
// the Supabase client, sending the same literal back round-trips cleanly.
export function bytesToPgHex(bytes: Uint8Array): string {
let out = '\\x';
for (let i = 0; i < bytes.length; i++) {
out += bytes[i]!.toString(16).padStart(2, '0');
}
return out;
}
export function pgHexToBytes(hex: string): Uint8Array {
if (!hex.startsWith('\\x')) {
throw new Error(`not a postgres hex literal: ${hex.slice(0, 8)}`);
}
const stripped = hex.slice(2);
if (stripped.length % 2 !== 0) throw new Error('odd hex length');
const out = new Uint8Array(stripped.length / 2);
for (let i = 0; i < stripped.length; i += 2) {
out[i / 2] = Number.parseInt(stripped.slice(i, i + 2), 16);
}
return out;
}
+17
View File
@@ -0,0 +1,17 @@
import { createClient as createSupabaseClient, type SupabaseClient } from '@supabase/supabase-js';
import type { Database, SupabaseConfig } from './types.js';
// Typed client alias used throughout the app.
export type AppSupabaseClient = SupabaseClient<Database>;
export function createClient(config: SupabaseConfig): AppSupabaseClient {
return createSupabaseClient<Database>(config.url, config.anonKey, {
auth: {
storage: config.sessionStorage,
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: config.detectSessionInUrl ?? false,
},
});
}
+3
View File
@@ -0,0 +1,3 @@
export * from './bytea.js';
export * from './client.js';
export * from './types.js';
+25
View File
@@ -0,0 +1,25 @@
import type { Database } from '@chat-app/db-types';
export type { Database };
// Storage contract used by Supabase auth. Both `expo-secure-store` and
// `@tauri-apps/plugin-store` can be wrapped to satisfy this.
export interface KeyValueStore {
getItem(key: string): Promise<string | null>;
setItem(key: string, value: string): Promise<void>;
removeItem(key: string): Promise<void>;
}
export interface SupabaseConfig {
url: string;
anonKey: string;
sessionStorage: KeyValueStore;
// Desktop Tauri webview may need this true to parse magic-link callbacks.
detectSessionInUrl?: boolean;
}
export type DevicePlatform = Database['public']['Enums']['device_platform'];
export type PresenceState = Database['public']['Enums']['presence_state'];
export type FriendshipStatus = Database['public']['Enums']['friendship_status'];
export type MemberRole = Database['public']['Enums']['member_role'];
export type ConversationType = Database['public']['Enums']['conversation_type'];