UNPKG

@chordcommerce/analytics

Version:

Chord Commerce event tracking

200 lines (199 loc) 9.14 kB
import type { AnyAnalytics, EventProperties, Options, ValidateResult, ChordAnalyticsOptions, AnyOptions, CartViewedInput, IdentifyTraits, CheckoutStartedInput, CheckoutStepCompletedInput, CheckoutStepViewedInput, EmailCapturedInput, ProductListViewedInput, ProductListFilteredInput, ProductAddedInput, ProductClickedInput, VariantClickedInput, ProductRemovedInput, ProductViewedInput, ProductsSearchedInput, CouponAppliedInput, CouponDeniedInput, CouponEnteredInput, CouponRemovedInput, SignedInInput, SignedOutInput, SignedUpInput, LoginStartedInput, ObjectTypes, OrderCompletedInput, SubscriptionCancelledInput, NavigationClickedInput, PaymentInfoEnteredInput } from '../types/index.js'; import { AnalyticsMiddleware } from '../types/client.js'; export interface ChordAnalyticsSnippet { _loadOptions: ChordAnalyticsOptions<ObjectTypes>; invoked: boolean; methods: string[]; queue: any[]; factory: (method: string) => () => ChordAnalytics; load: () => void; SNIPPET_VERSION: string; } export declare class ChordAnalytics<T extends ObjectTypes = ObjectTypes> { /** * Allows snippet.js to detect whether this library has been initialized yet. */ initialize: true; /** * Allows snippet.js to detect whether the snippet has started running yet. */ invoked: true; /** * Options for ChordAnalytics. */ options: ChordAnalyticsOptions<T>; /** * Middleware to be applied to the event properties */ middleware: any[]; /** * Promise that resolves when CDP is ready */ private cdpReadyPromise; private consentConfig; private resetCompletePromise; /** * Queue for events waiting for consent to be ready */ private consentEventQueue; /** * Whether we're currently waiting for consent and watching for it */ private consentWatcherActive; /** * Promise that resolves when consent is ready (shared across all queued events) */ private consentReadyPromise; constructor(options: ChordAnalyticsOptions<T>); /** * Persist the consent event queue to sessionStorage for recovery on instance recreation. * Validates queue size before storing to prevent QuotaExceededError. */ private persistQueueToStorage; /** * Restore pending events from sessionStorage (keeps events less than 5 min old). * Called on new instance initialization. */ private restoreQueueFromStorage; /** * Clear the persisted queue from sessionStorage after successful flush. */ private clearQueueFromStorage; /** * Initialize CDP snippet and wait for it to be ready. * Fires initial consent track event after CDP is fully initialized to avoid circular await. */ private initializeCdp; /** * Set debug mode for Chord Analytics * @param enabled - Whether debug mode should be enabled */ setDebugMode: (enabled: boolean) => void; cdp: () => AnyAnalytics; ccdp: () => AnyAnalytics; logger: (message?: any, ...optionalParams: any[]) => void; isResetting: () => boolean; private waitForReadyState; /** * Wait for consent manager to be ready (no timeout - queues indefinitely). * Uses a shared promise so multiple events share the same watcher. */ private waitForConsent; /** * Queue an event to be sent when consent is ready. * Persists to sessionStorage for recovery on instance recreation. * Starts a consent watcher if not already active. */ private queueEventForConsent; /** * Watch for consent to become ready, then flush the queue. */ private watchForConsentAndFlush; /** * Flush all queued events now that consent is ready. * Clears sessionStorage after successful flush. */ private flushConsentQueue; /** * Configure CDP with fresh consent categories before each event. * Uses Jitsu's configure() to update privacy.consentCategories. */ private configureConsentOnCdp; validate: (event: string, props: EventProperties) => ValidateResult[]; /** * Generate the event `meta` property. */ meta: () => { ownership: { oms_id: string; store_id: string; tenant_id: string; }; version: { major: number; minor: number; patch: number; }; i18n: import("../types/client.js").i18nMetadata; platform: import("../types/client.js").platformMetadata; store: import("../types/client.js").storeMetadata; }; addSourceMiddleware: (func: AnalyticsMiddleware) => void; /** * Send a `track` event to the CDP with any event name and properties. * If consent is not ready, the event is queued until consent is available. */ track: (event: string, props?: EventProperties, options?: Options) => Promise<void>; /** * Internal method to actually send a track event to CDP. */ private sendTrackEvent; /** * Send an `identify` event to the CDP with user id and traits. * If consent is not ready, the event is queued until consent is available. */ identify: { (userId?: string, traits?: IdentifyTraits, options?: AnyOptions): Promise<void>; (traits?: IdentifyTraits, options?: AnyOptions): Promise<void>; }; /** * Internal method to actually send an identify event to CDP. */ private sendIdentifyEvent; /** * Send a `page` event to the CDP. * If consent is not ready, the event is queued until consent is available. */ page: { (props?: Record<string, any>, options?: Options): void; }; /** * Internal method to actually send a page event to CDP. */ private sendPageEvent; reset: () => Promise<void>; private performReset; /** * Handler for postMessage events from the Shopify Web Pixel sandbox. * Bound to the instance for proper `this` context and cleanup. */ private webPixelMessageHandler; /** * Set up a listener for postMessage events from the Shopify Web Pixel sandbox. * This allows the web pixel (running in Shopify's sandboxed iframe) * to forward analytics events to this ChordAnalytics instance on the storefront. * * The web pixel sends messages in the format: * - { source: 'chord-web-pixel', type: 'track', payload: [eventName, properties] } * - { source: 'chord-web-pixel', type: 'identify', payload: [userId, traits] } * - { source: 'chord-web-pixel', type: 'page', payload: [properties] } * * @returns A cleanup function to remove the listener */ setupWebPixelListener: () => (() => void); trackCartViewed: (props: CartViewedInput<T>, options?: AnyOptions) => Promise<void>; trackCheckoutStarted: (props: CheckoutStartedInput<T>, options?: AnyOptions) => Promise<void>; trackCheckoutStepCompleted: (props: CheckoutStepCompletedInput, options?: AnyOptions) => Promise<void>; trackCheckoutStepViewed: (props: CheckoutStepViewedInput, options?: AnyOptions) => Promise<void>; trackCouponApplied: (props: CouponAppliedInput, options?: AnyOptions) => Promise<void>; trackCouponDenied: (props: CouponDeniedInput, options?: AnyOptions) => Promise<void>; trackCouponEntered: (props: CouponEnteredInput, options?: AnyOptions) => Promise<void>; trackCouponRemoved: (props: CouponRemovedInput, options?: AnyOptions) => Promise<void>; trackEmailCaptured: (props: EmailCapturedInput, options?: AnyOptions) => Promise<void>; trackProductAdded: (props: ProductAddedInput<T>, options?: AnyOptions) => Promise<void>; trackProductClicked: (props: ProductClickedInput<T>, options?: AnyOptions) => Promise<void>; trackVariantClicked: (props: VariantClickedInput<T>, options?: AnyOptions) => Promise<void>; trackProductListFiltered: (props: ProductListFilteredInput, options?: AnyOptions) => Promise<void>; trackProductListViewed: (props: ProductListViewedInput<T>, options?: AnyOptions) => Promise<void>; trackProductRemoved: (props: ProductRemovedInput<T>, options?: AnyOptions) => Promise<void>; trackProductViewed: (props: ProductViewedInput<T>, options?: AnyOptions) => Promise<void>; trackProductsSearched: (props: ProductsSearchedInput, options?: AnyOptions) => Promise<void>; trackSignedIn: (props: SignedInInput, options?: AnyOptions) => Promise<void>; trackSignedOut: (props?: SignedOutInput, options?: AnyOptions) => Promise<void>; trackSignedUp: (props?: SignedUpInput, options?: AnyOptions) => Promise<void>; trackLoginStarted: (props: LoginStartedInput, options?: AnyOptions) => Promise<void>; trackSubscriptionCancelled: (props: SubscriptionCancelledInput, options?: AnyOptions) => Promise<void>; trackNavigationClicked: (props: NavigationClickedInput, options?: AnyOptions) => Promise<void>; trackPaymentInfoEntered: (props: PaymentInfoEnteredInput, options?: AnyOptions) => Promise<void>; trackOrderCompleted: (props: OrderCompletedInput, options?: AnyOptions) => Promise<void>; }