waitlist-mailer
Version:
Modern, modular TypeScript library for managing waitlists with pluggable storage and mail providers. Supports MongoDB, SQL databases, and custom adapters with zero required dependencies for basic usage.
144 lines (142 loc) • 4.74 kB
TypeScript
/**
* @fileoverview Core types and interfaces for the waitlist-mailer library.
* Defines contracts for storage providers, mail providers, and data structures.
*/
/**
* Represents a single entry in the waitlist.
* @template T - Optional metadata type for custom fields
*/
interface WaitlistEntry<T = any> {
/** Email address */
email: string;
/** Custom metadata (e.g., name, referral source, etc.) */
metadata?: T;
/** Entry creation timestamp */
createdAt: Date;
}
/**
* Result of a join operation.
*/
interface JoinResult {
success: boolean;
message: string;
email?: string;
}
/**
* Storage provider interface that must be implemented by all storage adapters.
* Allows pluggable backends (memory, MongoDB, PostgreSQL, MySQL, etc.)
* @template T - Optional metadata type for custom fields
*/
interface StorageProvider<T = any> {
/**
* Optional lifecycle hook: connect to the storage backend.
* Called during initialization if provided.
*/
connect?(): Promise<void>;
/**
* Add an email to storage with optional metadata.
* @param email - The email address to add
* @param data - Optional custom metadata
* @throws {Error} If email already exists or storage fails
*/
add(email: string, data?: T): Promise<void>;
/**
* Remove an email from storage.
* @param email - The email address to remove
* @returns true if the email was found and removed, false otherwise
*/
remove(email: string): Promise<boolean>;
/**
* Check if an email exists in storage.
* @param email - The email address to check
* @returns true if the email exists, false otherwise
*/
exists(email: string): Promise<boolean>;
/**
* Retrieve all entries from storage.
* @returns Array of WaitlistEntry objects
*/
getAll(): Promise<WaitlistEntry<T>[]>;
/**
* Search entries by email pattern.
* Delegates filtering to the storage layer for efficiency.
* @param pattern - The pattern to search for (partial email match)
* @param options - Optional search options
* @returns Array of matching WaitlistEntry objects
*/
search?(pattern: string, options?: SearchOptions): Promise<WaitlistEntry<T>[]>;
/**
* Iterate over entries using a cursor/stream pattern.
* Useful for processing large datasets without loading everything into memory.
* @param batchSize - Number of entries to fetch per batch
* @returns AsyncIterableIterator for streaming entries
*/
iterate?(batchSize?: number): AsyncIterableIterator<WaitlistEntry<T>>;
/**
* Count total entries in storage.
*/
count(): Promise<number>;
/**
* Clear all entries from storage.
*/
clear(): Promise<void>;
/**
* Optional lifecycle hook: disconnect from the storage backend.
* Called during cleanup if provided.
*/
disconnect?(): Promise<void>;
}
/**
* Mail provider interface that must be implemented by all mail adapters.
* Allows pluggable mail backends (Nodemailer, SendGrid, Mailgun, etc.)
*/
interface MailProvider {
/**
* Send a confirmation email to the specified address.
* @param email - The recipient email address
* @param context - Context object with template variables
* @returns true if the email was sent successfully, false otherwise
*/
sendConfirmation(email: string, context: Record<string, any>): Promise<boolean>;
/**
* Optional lifecycle hook: verify mail provider configuration.
*/
verify?(): Promise<boolean>;
}
/**
* Configuration options for WaitlistManager.
* @template T - Optional metadata type for custom fields
*/
interface WaitlistManagerConfig<T = any> {
/** * Storage provider instance.
* Defaults to MemoryStorage if not provided.
*/
storage?: StorageProvider<T>;
/** Optional mail provider instance */
mailer?: MailProvider;
/** Optional company name for email context */
companyName?: string;
/** Enable automatic initialization on construction */
autoConnect?: boolean;
}
/**
* Email sending context passed to mail providers.
*/
interface EmailContext {
email: string;
companyName?: string;
customUrl?: string;
[key: string]: any;
}
/**
* Options for search operations.
*/
interface SearchOptions {
/** Maximum number of results to return */
limit?: number;
/** Number of results to skip (for pagination) */
offset?: number;
/** Whether to use case-insensitive matching (default: true) */
caseInsensitive?: boolean;
}
export type { EmailContext, JoinResult, MailProvider, SearchOptions, StorageProvider, WaitlistEntry, WaitlistManagerConfig };