import { describe, it, expect } from 'vitest'; import { createAnonClient } from './setup.ts'; const client = createAnonClient(); describe('Realtime', () => { it('should resume subscription from last_event_id', async () => { console.log('Starting realtime test'); // 1. Create a message while no one is listening console.log('Step 1: Creating test record'); const { data: inserted, error } = await client .from('todos') .insert({ title: 'Missed Event', completed: false }) .select() .single(); expect(error).toBeNull(); console.log('Created record:', inserted); // We need to know the ID of this event in realtime history. // Ideally we query `madbase_realtime.messages` but client can't. // So we just assume ID > 0. // Wait, we need to pass `last_event_id` < actual_id. // Let's assume we want everything after ID=0. return new Promise((resolve, reject) => { console.log('Step 2: Creating channel with last_event_id=0'); // 2. Connect with last_event_id = 0 (should fetch all history) const channel = client .channel('public:todos', { config: { last_event_id: 0 } as any }) .on( 'postgres_changes', { event: 'INSERT', schema: 'public', table: 'todos' }, (payload) => { console.log('Received missed event:', payload); if (payload.new && payload.new.title === 'Missed Event') { expect(payload.new.id).toBe(inserted.id); client.removeChannel(channel).then(() => resolve()); } } ) .subscribe((status, err) => { console.log('Channel status:', status, 'Error:', err); if (status === 'SUBSCRIBED') { console.log('Subscribed with resume'); } if (status === 'CHANNEL_ERROR') { console.error('Channel error:', err); reject(err || new Error('Unknown channel error')); } if (status === 'TIMED_OUT') { console.error('Channel timeout'); reject(new Error('Channel connection timeout')); } if (status === 'CLOSED') { console.error('Channel closed'); reject(new Error('Channel closed unexpectedly')); } }); setTimeout(() => { reject(new Error('Timeout waiting for missed event')); }, 5000); }); }); });