import { SmrtCollection } from '@happyvertical/smrt-core'; import { AnalyticsEvent } from '../models/AnalyticsEvent.js'; import { PropertyStatsWithTrend, TrackingEventStatus } from '../types/index.js'; export declare class AnalyticsEventCollection extends SmrtCollection { static readonly _itemClass: typeof AnalyticsEvent; /** * Offset of `timeZone` at `instant`, in milliseconds (wall-clock minus UTC). * * Reads the zone's wall-clock Y/M/D h:m:s for `instant` via * `Intl.DateTimeFormat` parts and subtracts the real UTC instant. Positive * east of UTC, negative west (e.g. `America/Los_Angeles` returns roughly * `-7h`/`-8h` depending on DST). * * @throws RangeError if `timeZone` is not a valid IANA identifier. */ private zoneOffsetMs; /** * Resolve the UTC instant marking the start of the calendar day (00:00) that * `instant` falls on **within the given IANA time zone**. * * Day-over-day buckets ("today vs yesterday") must respect the property's * configured `timeZone` (defaults to `America/Los_Angeles`), otherwise a * pageview at 11:30pm local time — already the next UTC day — is bucketed * into the wrong day. We read the wall-clock civil date for the zone, then * map that date's local midnight back to a UTC instant, correcting for the * zone offset (and re-correcting once across a DST boundary). * * Invalid/unknown zone identifiers fall back to UTC day boundaries (matching * the previous behaviour) rather than throwing. * * @param instant - Reference instant. * @param timeZone - IANA time zone (e.g. `America/Los_Angeles`). * @returns UTC `Date` for local midnight of the day `instant` is in. */ protected startOfDayInZone(instant: Date, timeZone: string): Date; /** * Resolve the UTC instant for the start of the day *before* `todayStart`'s * local day, in `timeZone`. * * Steps back 12h from local midnight (landing safely inside the previous * civil day regardless of DST — a naive `- 24h` skips a day across * spring-forward), then re-resolves start-of-day. * * @param todayStart - Local-midnight UTC instant from {@link startOfDayInZone}. * @param timeZone - IANA time zone. * @returns UTC `Date` for local midnight of the prior calendar day. */ protected startOfYesterdayInZone(todayStart: Date, timeZone: string): Date; /** * Classify a day-over-day change into a trend direction + percent. * * - `yesterday > 0`: percent = rounded delta; >5% up, <-5% down, else flat. * - `yesterday === 0 && today > 0`: a brand-new surge from a zero baseline — * classified `up` with a `null` percent (no finite percentage exists), so * the UI renders "new" rather than a misleading flat 0%. * - `yesterday === 0 && today === 0`: flat, 0%. * * @param today - Today's count. * @param yesterday - Yesterday's count. * @returns Trend direction and percent (null when growing from zero). */ protected classifyTrend(today: number, yesterday: number): { trend: 'up' | 'down' | 'flat'; trendPercent: number | null; }; /** * Find events by property * * @param propertyId - Parent property ID * @returns Array of events */ findByProperty(propertyId: string): Promise; /** * Find events by event name * * @param eventName - Event name to filter by * @returns Array of matching events */ findByEventName(eventName: string): Promise; /** * Find events by client ID * * @param clientId - Client ID * @returns Array of events for this client */ findByClientId(clientId: string): Promise; /** * Find events by user ID * * @param userId - User ID * @returns Array of events for this user */ findByUserId(userId: string): Promise; /** * Find events by status * * @param status - Tracking event status * @returns Array of matching events */ findByStatus(status: TrackingEventStatus): Promise; /** * Find all pending events */ findPending(): Promise; /** * Find all sent events */ findSent(): Promise; /** * Find all failed events */ findFailed(): Promise; /** * Find events that should be retried * * @param maxRetries - Maximum retry count * @returns Array of events eligible for retry */ findForRetry(maxRetries?: number): Promise; /** * Find pending events for a property * * @param propertyId - Parent property ID * @returns Array of pending events */ findPendingByProperty(propertyId: string): Promise; /** * Find events by date range * * @param startDate - Start date * @param endDate - End date * @returns Array of events in date range */ findByDateRange(startDate: Date, endDate: Date): Promise; /** * Find conversion events * * @param propertyId - Optional property ID filter * @returns Array of conversion events */ findConversions(propertyId?: string): Promise; /** * Find pageview events * * @param propertyId - Optional property ID filter * @returns Array of pageview events */ findPageviews(propertyId?: string): Promise; /** * Count events by event name for a property * * @param propertyId - Property ID * @returns Map of event name to count */ countByEventName(propertyId: string): Promise>; /** * Get event stats for a property * * @param propertyId - Property ID * @returns Event statistics */ getPropertyStats(propertyId: string): Promise<{ total: number; pending: number; sent: number; failed: number; conversions: number; pageviews: number; }>; /** * Get day-over-day pageview stats with trend for a property. * * Compares today's pageview count against yesterday's to produce a * trend direction and percentage change. A threshold of 5% is used * to classify 'up' vs 'down' vs 'flat'; growth from a zero baseline is * classified `up` with a `null` percent (see {@link classifyTrend}). * * Day boundaries are computed in `timeZone` (an IANA identifier such as the * property's `AnalyticsProperty.timeZone`, which defaults to * `America/Los_Angeles`) so an event near local midnight buckets into the * correct calendar day. Defaults to `'UTC'` when omitted. * * @param propertyId - Property ID * @param now - Optional current date (for testing) * @param timeZone - IANA time zone for day boundaries (default `'UTC'`) * @returns Stats with trend */ getPropertyStatsWithTrend(propertyId: string, now?: Date, timeZone?: string): Promise; /** * Get day-over-day stats for multiple properties in batch. * * Day boundaries are computed in `timeZone` (default `'UTC'`); see * {@link getPropertyStatsWithTrend}. A single zone applies to the whole * batch, so callers mixing properties with different `timeZone` values * should batch per zone (or fall back to per-property calls). * * @param propertyIds - Array of property IDs * @param now - Optional current date (for testing) * @param timeZone - IANA time zone for day boundaries (default `'UTC'`) * @returns Map of propertyId to stats */ getBatchPropertyStats(propertyIds: string[], now?: Date, timeZone?: string): Promise>; } //# sourceMappingURL=AnalyticsEventCollection.d.ts.map