119 lines
3.9 KiB
TypeScript
119 lines
3.9 KiB
TypeScript
'use server';
|
|
|
|
import { getImapConnection, getEmails, getEmailContent } from './email-service';
|
|
import {
|
|
cacheEmailList,
|
|
cacheEmailContent,
|
|
cacheImapSession
|
|
} from '@/lib/redis';
|
|
|
|
/**
|
|
* Prefetch basic email data for faster initial loading
|
|
* This function should be called when a user logs in
|
|
*/
|
|
export async function prefetchUserEmailData(userId: string): Promise<void> {
|
|
console.log(`Starting email prefetch for user ${userId}`);
|
|
const startTime = Date.now();
|
|
|
|
try {
|
|
// Connect to IMAP server
|
|
const client = await getImapConnection(userId);
|
|
|
|
// 1. Prefetch mailbox list
|
|
const mailboxes = await client.list();
|
|
const mailboxPaths = mailboxes.map(mailbox => mailbox.path);
|
|
|
|
// Cache mailbox list in session data
|
|
await cacheImapSession(userId, {
|
|
lastActive: Date.now(),
|
|
mailboxes: mailboxPaths
|
|
});
|
|
|
|
console.log(`Prefetched ${mailboxPaths.length} folders for user ${userId}`);
|
|
|
|
// 2. Prefetch email lists for important folders
|
|
const importantFolders = [
|
|
'INBOX',
|
|
mailboxPaths.find(path => path.toLowerCase().includes('sent')) || 'Sent',
|
|
mailboxPaths.find(path => path.toLowerCase().includes('draft')) || 'Drafts'
|
|
].filter(Boolean);
|
|
|
|
// Fetch first page of each important folder
|
|
for (const folder of importantFolders) {
|
|
try {
|
|
console.log(`Prefetching emails for ${folder}`);
|
|
const emailList = await getEmails(userId, folder, 1, 20);
|
|
console.log(`Prefetched ${emailList.emails.length} emails for ${folder}`);
|
|
} catch (error) {
|
|
console.error(`Error prefetching emails for folder ${folder}:`, error);
|
|
// Continue with other folders even if one fails
|
|
}
|
|
}
|
|
|
|
// 3. Prefetch content of recent unread emails in INBOX
|
|
try {
|
|
// Get the list again (it's already cached so this will be fast)
|
|
const inboxList = await getEmails(userId, 'INBOX', 1, 20);
|
|
|
|
// Prefetch content for up to 5 recent unread emails
|
|
const unreadEmails = inboxList.emails
|
|
.filter(email => !email.flags.seen)
|
|
.slice(0, 5);
|
|
|
|
if (unreadEmails.length > 0) {
|
|
console.log(`Prefetching content for ${unreadEmails.length} unread emails`);
|
|
|
|
// Fetch content in parallel for speed
|
|
await Promise.allSettled(
|
|
unreadEmails.map(email =>
|
|
getEmailContent(userId, email.id, 'INBOX')
|
|
.catch(err => console.error(`Error prefetching email ${email.id}:`, err))
|
|
)
|
|
);
|
|
|
|
console.log(`Completed prefetching content for unread emails`);
|
|
}
|
|
} catch (error) {
|
|
console.error('Error prefetching unread email content:', error);
|
|
}
|
|
|
|
const duration = (Date.now() - startTime) / 1000;
|
|
console.log(`Email prefetch completed for user ${userId} in ${duration.toFixed(2)}s`);
|
|
} catch (error) {
|
|
console.error('Error during email prefetch:', error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Prefetch a specific folder's emails
|
|
* This can be used when the user navigates to a folder to preload more pages
|
|
*/
|
|
export async function prefetchFolderEmails(
|
|
userId: string,
|
|
folder: string,
|
|
pages: number = 3
|
|
): Promise<void> {
|
|
try {
|
|
console.log(`Prefetching ${pages} pages of emails for folder ${folder}`);
|
|
|
|
// Fetch multiple pages in parallel
|
|
await Promise.allSettled(
|
|
Array.from({ length: pages }, (_, i) => i + 1).map(page =>
|
|
getEmails(userId, folder, page, 20)
|
|
.catch(err => console.error(`Error prefetching page ${page} of ${folder}:`, err))
|
|
)
|
|
);
|
|
|
|
console.log(`Completed prefetching ${pages} pages of ${folder}`);
|
|
} catch (error) {
|
|
console.error(`Error prefetching folder ${folder}:`, error);
|
|
}
|
|
}
|
|
|
|
export async function warmupRedisCache() {
|
|
// Ping Redis to establish connection early
|
|
const redis = getRedisClient();
|
|
await redis.ping();
|
|
console.log('Redis connection warmed up');
|
|
return true;
|
|
}
|