@yesplz-ai/analytics-react-native 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -83,34 +83,41 @@ var GaEventTypeReverse = {
83
83
  remove_from_wishlist: EventType.UnfavoriteProduct
84
84
  };
85
85
  var ItemListId = {
86
- SEARCH_RESULTS: "search-results",
87
- PRODUCT_LIST: "product-list",
88
- YOU_MAY_ALSO_LIKE: "you-may-also-like",
89
- COMPLETE_THE_LOOK: "complete-the-look",
90
- COLLABORATIVE_FILTERING: "collaborative-filtering",
91
- MORE_FROM_BRAND: "more-from-brand",
92
- STYLE_WITH: "style-with",
93
- SHOPPING_CART: "shopping-cart",
86
+ SEARCH_RESULTS: "search_results",
87
+ PRODUCT_LIST: "category",
88
+ YOU_MAY_ALSO_LIKE: "rec_YMAL",
89
+ COMPLETE_THE_LOOK: "rec_CTL",
90
+ COLLABORATIVE_FILTERING: "rec_CF",
91
+ MORE_FROM_BRAND: "rec_Brand",
92
+ STYLE_WITH: "STW",
93
+ SHOPPING_CART: "rec_CART",
94
94
  ITEM_FOR_YOU: "item-for-you",
95
95
  BRAND_FOR_YOU: "brand-for-you"
96
96
  };
97
97
  var LIST_ID_ALIASES = {
98
98
  Search: ItemListId.SEARCH_RESULTS,
99
+ search_results: ItemListId.SEARCH_RESULTS,
99
100
  "search-results": ItemListId.SEARCH_RESULTS,
100
101
  PLP: ItemListId.PRODUCT_LIST,
102
+ category: ItemListId.PRODUCT_LIST,
101
103
  "product-list": ItemListId.PRODUCT_LIST,
102
104
  YMAL: ItemListId.YOU_MAY_ALSO_LIKE,
105
+ rec_YMAL: ItemListId.YOU_MAY_ALSO_LIKE,
103
106
  "you-may-also-like": ItemListId.YOU_MAY_ALSO_LIKE,
104
107
  CTL: ItemListId.COMPLETE_THE_LOOK,
108
+ rec_CTL: ItemListId.COMPLETE_THE_LOOK,
105
109
  "complete-the-look": ItemListId.COMPLETE_THE_LOOK,
106
110
  CF: ItemListId.COLLABORATIVE_FILTERING,
111
+ rec_CF: ItemListId.COLLABORATIVE_FILTERING,
107
112
  "collaborative-filtering": ItemListId.COLLABORATIVE_FILTERING,
108
113
  "frequently-bought-together": ItemListId.COLLABORATIVE_FILTERING,
109
114
  Brand: ItemListId.MORE_FROM_BRAND,
115
+ rec_Brand: ItemListId.MORE_FROM_BRAND,
110
116
  "more-from-brand": ItemListId.MORE_FROM_BRAND,
111
117
  STW: ItemListId.STYLE_WITH,
112
118
  "style-with": ItemListId.STYLE_WITH,
113
119
  CART: ItemListId.SHOPPING_CART,
120
+ rec_CART: ItemListId.SHOPPING_CART,
114
121
  "shopping-cart": ItemListId.SHOPPING_CART,
115
122
  "item-for-you": ItemListId.ITEM_FOR_YOU,
116
123
  "brand-for-you": ItemListId.BRAND_FOR_YOU
@@ -332,6 +339,7 @@ async function sendToGA(eventType, props, options) {
332
339
  engagement_time_msec: 1,
333
340
  session_engaged: "1"
334
341
  };
342
+ if (options.debug) params.debug_mode = true;
335
343
  if (currency) params.currency = currency;
336
344
  if (value !== void 0) params.value = value;
337
345
  if (transaction_id) params.transaction_id = transaction_id;
@@ -636,6 +644,14 @@ var Analytics = class {
636
644
  if (props.id && !Array.isArray(props.items)) {
637
645
  props.items = [{ item_id: props.id, ...props }];
638
646
  }
647
+ if (props.item_list_id) {
648
+ props.item_list_id = normalizeItemListId(props.item_list_id) || void 0;
649
+ }
650
+ if (Array.isArray(props.items)) {
651
+ props.items = props.items.map(
652
+ (item) => item.item_list_id ? { ...item, item_list_id: normalizeItemListId(item.item_list_id) || void 0 } : item
653
+ );
654
+ }
639
655
  const metadata = this.collectMetadata();
640
656
  Object.assign(props, metadata);
641
657
  props.data_provider = "yesplz";
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/analytics.ts","../src/constants.ts","../src/storage.ts","../src/ids.ts","../src/attribution.ts","../src/ga.ts","../src/beacon.ts"],"sourcesContent":["export { analytics, Analytics } from './analytics';\nexport {\n EventType,\n ItemListId,\n normalizeItemListId,\n VERSION,\n} from './constants';\nexport type {\n EventTypeValue,\n ItemListIdValue,\n} from './constants';\nexport type {\n AnalyticsConfig,\n TrackItem,\n TrackProperties,\n ApiEvent,\n EventMetadata,\n} from './types';\n","import { Platform, AppState, type AppStateStatus } from 'react-native';\nimport {\n API_EVENTS,\n EventType,\n GaEventType,\n GaEventTypeReverse,\n VERSION,\n} from './constants';\nimport { Storage, StorageKeys } from './storage';\nimport {\n generateId,\n loadIdentity,\n numericSessionId,\n saveSession,\n saveUser,\n clearUser as clearUserStorage,\n} from './ids';\nimport { handleAttribution } from './attribution';\nimport { sendToGA } from './ga';\nimport { Beacon } from './beacon';\nimport type {\n AnalyticsConfig,\n ApiEvent,\n EventMetadata,\n TrackProperties,\n} from './types';\n\nconst DEFAULT_DEBOUNCE_MS = 1000;\nconst DEFAULT_API_BASE_URL = 'https://api.yesplz.ai';\nconst DEFAULT_GA_PROXY_BASE_URL = 'https://ypsh-admin.yesplz.ai/api/mp/collect';\n\nfunction buildUserAgent(): string {\n const os = Platform.OS;\n const version = Platform.Version;\n return `YesPlzSDK-RN/${VERSION} (${os}; ${String(version)})`;\n}\n\nexport class Analytics {\n private config: Required<\n Pick<AnalyticsConfig, 'debug' | 'debounceMs' | 'cacheUserId' | 'idPrefix'>\n > &\n Omit<AnalyticsConfig, 'debug' | 'debounceMs' | 'cacheUserId' | 'idPrefix'> & {\n appId?: string;\n gaProxyUrl?: string;\n } = {\n debug: false,\n debounceMs: DEFAULT_DEBOUNCE_MS,\n cacheUserId: true,\n idPrefix: '',\n };\n\n private cid: string | null = null;\n private sessionId: string | null = null;\n private userId: string | null = null;\n private userProperties: Record<string, unknown> = {};\n private isInitialized = false;\n private initPromise: Promise<void> | null = null;\n private beacon: Beacon | null = null;\n private pendingTracks: { eventType: string; properties: TrackProperties }[] = [];\n private appStateSubscription: { remove(): void } | null = null;\n\n init(appId: string, config: AnalyticsConfig = {}): Analytics {\n if (this.isInitialized || this.initPromise) return this;\n this.initPromise = this.initInternal(appId, config);\n void this.initPromise;\n return this;\n }\n\n ready(): Promise<void> {\n return this.initPromise ?? Promise.resolve();\n }\n\n private async initInternal(appId: string, config: AnalyticsConfig): Promise<void> {\n const normalizedAppId = String(appId).trim();\n if (!normalizedAppId) {\n throw new Error('[YesPlz Analytics] appId must be a non-empty string');\n }\n\n const apiBaseUrl = (config.apiBaseUrl || DEFAULT_API_BASE_URL).replace(/\\/$/, '');\n const apiEndpoint =\n config.apiEndpoint ||\n `${apiBaseUrl}/api/v1/retailer/${encodeURIComponent(normalizedAppId)}/interactions/`;\n const gaProxyBaseUrl = config.gaProxyBaseUrl || DEFAULT_GA_PROXY_BASE_URL;\n const gaProxySep = gaProxyBaseUrl.includes('?') ? '&' : '?';\n const gaProxyUrl = `${gaProxyBaseUrl}${gaProxySep}shop=${encodeURIComponent(normalizedAppId)}`;\n\n const mergedDefaultParams: Record<string, unknown> = {\n ...(config.defaultParams || {}),\n };\n if (config.testMarker) {\n mergedDefaultParams.test_marker = config.testMarker;\n }\n\n this.config = {\n ...this.config,\n appId: normalizedAppId,\n apiEndpoint,\n apiBaseUrl,\n apiToken: config.apiToken ?? null,\n gaProxyBaseUrl,\n gaProxyUrl,\n idPrefix: config.idPrefix || '',\n defaultParams: mergedDefaultParams,\n testMarker: config.testMarker,\n debug: config.debug ?? false,\n cacheUserId: config.cacheUserId ?? true,\n debounceMs: config.debounceMs || DEFAULT_DEBOUNCE_MS,\n };\n\n const identity = await loadIdentity();\n this.cid = identity.cid;\n this.sessionId = identity.sessionId;\n this.userId = identity.userId;\n this.userProperties = identity.userProperties;\n\n if (config.userId) {\n await this.setUserInternal(config.userId, config.userProperties || {});\n }\n\n if (apiEndpoint) {\n this.beacon = new Beacon({\n apiEndpoint,\n apiToken: this.config.apiToken,\n defaultParams: this.config.defaultParams,\n idPrefix: this.config.idPrefix,\n debounceMs: this.config.debounceMs,\n debug: this.config.debug,\n });\n await this.beacon.restorePending();\n }\n\n this.appStateSubscription = AppState.addEventListener(\n 'change',\n (state: AppStateStatus) => {\n if (state === 'background' || state === 'inactive') {\n void this.beacon?.savePending();\n }\n }\n );\n\n this.isInitialized = true;\n this.log('Initialized');\n\n const queued = this.pendingTracks.splice(0, this.pendingTracks.length);\n for (const item of queued) {\n void this.dispatchTrack(item.eventType, item.properties);\n }\n }\n\n async setUser(\n userId: string | null,\n userProperties: Record<string, unknown> = {}\n ): Promise<Analytics> {\n await this.ready();\n if (userId === null) {\n this.userId = null;\n this.userProperties = {};\n await clearUserStorage();\n this.log('User cleared');\n return this;\n }\n await this.setUserInternal(userId, userProperties);\n return this;\n }\n\n private async setUserInternal(\n userId: string,\n userProperties: Record<string, unknown>\n ): Promise<void> {\n const id = String(userId);\n if (id.length === 0) {\n // eslint-disable-next-line no-console\n console.error('[YesPlz Analytics] User ID must be a non-empty value');\n return;\n }\n this.userId = id;\n this.userProperties = JSON.parse(JSON.stringify(userProperties));\n await saveUser(this.userId, this.userProperties, this.config.cacheUserId);\n this.log(`User set: ${id}`);\n }\n\n getUser(): { userId: string; userProperties: Record<string, unknown> } | null {\n if (!this.userId) return null;\n return { userId: this.userId, userProperties: this.userProperties };\n }\n\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n getClientId(): string | null {\n return this.cid;\n }\n\n track(eventType: string, properties: TrackProperties = {}): Analytics {\n if (typeof eventType !== 'string' || eventType.length === 0) {\n // eslint-disable-next-line no-console\n console.error('[YesPlz Analytics] Event type must be a non-empty string');\n return this;\n }\n\n if (!this.isInitialized) {\n this.pendingTracks.push({\n eventType,\n properties: JSON.parse(JSON.stringify(properties)),\n });\n return this;\n }\n\n void this.dispatchTrack(eventType, properties);\n return this;\n }\n\n private async dispatchTrack(\n eventType: string,\n properties: TrackProperties\n ): Promise<void> {\n const props: TrackProperties = JSON.parse(JSON.stringify(properties));\n\n await handleAttribution(eventType, props, this.config.idPrefix);\n\n if (eventType === EventType.Purchase && !props.transaction_id) {\n props.transaction_id = generateId();\n }\n\n if (props.id && !Array.isArray(props.items)) {\n props.items = [{ item_id: props.id, ...(props as Record<string, unknown>) }];\n }\n\n const metadata = this.collectMetadata();\n Object.assign(props, metadata);\n props.data_provider = 'yesplz';\n if (this.config.testMarker) {\n props.test_marker = this.config.testMarker;\n }\n\n await this.sendGA(eventType, props);\n\n const apiEventType = GaEventTypeReverse[eventType] || eventType;\n if (API_EVENTS.includes(apiEventType)) {\n this.queueApi(apiEventType, props, metadata);\n }\n }\n\n private async sendGA(eventType: string, props: TrackProperties): Promise<void> {\n if (!this.config.gaProxyUrl) return;\n if (!this.cid || !this.sessionId) return;\n\n const gaEventName = GaEventType[eventType] ?? eventType;\n await sendToGA(eventType, props, {\n gaProxyUrl: this.config.gaProxyUrl,\n clientId: this.cid,\n sessionId: this.sessionId,\n numericSessionId: numericSessionId(this.sessionId),\n userId: this.userId,\n debug: this.config.debug,\n });\n this.log(`Track: ${gaEventName}`, props.items?.length ? { items: props.items.length } : undefined);\n }\n\n private queueApi(\n eventType: string,\n props: TrackProperties,\n metadata: EventMetadata\n ): void {\n if (!this.beacon) return;\n const items = props.items && props.items.length > 0 ? props.items : [props];\n const fallbackUrl = `app://${this.config.appId ?? 'yesplz'}/`;\n const url =\n typeof props.page_location === 'string' && props.page_location.length > 0\n ? props.page_location\n : fallbackUrl;\n const referrerUrl =\n typeof props.page_referrer === 'string' && props.page_referrer.length > 0\n ? props.page_referrer\n : null;\n\n const events: ApiEvent[] = items.map((item) => {\n const merged: Record<string, unknown> = {\n ...(props as Record<string, unknown>),\n ...(item as Record<string, unknown>),\n ...metadata,\n };\n const itemId = (item as { item_id?: string }).item_id;\n if (itemId) merged.id = itemId;\n merged.identifier_type = eventType.startsWith('yp_brand_')\n ? 'brand_name'\n : 'product_id';\n\n const event: ApiEvent = {\n event_type: eventType,\n url,\n referrer_url: referrerUrl,\n user_id: this.userId,\n session_id: this.sessionId,\n extra_data: merged,\n };\n if (Object.keys(this.userProperties).length > 0) {\n event.extra_user_data = this.userProperties;\n }\n return event;\n });\n\n this.beacon.enqueueAll(events);\n }\n\n private collectMetadata(): EventMetadata {\n const metadata: EventMetadata = {\n yp_client_time: Date.now(),\n yp_platform: Platform.OS,\n yp_platform_version: String(Platform.Version),\n yp_user_agent: buildUserAgent(),\n yp_timezone_offset: new Date().getTimezoneOffset(),\n };\n try {\n metadata.yp_timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n // ignore\n }\n if (this.cid) metadata.google_client_id = this.cid;\n return metadata;\n }\n\n async flush(): Promise<Analytics> {\n await this.ready();\n await this.beacon?.flush();\n return this;\n }\n\n async reset(): Promise<Analytics> {\n await this.ready();\n this.userId = null;\n this.userProperties = {};\n await clearUserStorage();\n await Storage.removeItem(StorageKeys.PENDING_EVENTS);\n await Storage.removeItem(StorageKeys.ATTRIBUTION);\n const newSession = generateId();\n this.sessionId = newSession;\n await saveSession(newSession);\n this.log('Reset');\n return this;\n }\n\n teardown(): void {\n this.appStateSubscription?.remove();\n this.appStateSubscription = null;\n }\n\n private log(message: string, data?: unknown): void {\n if (this.config.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] ${message}`, data ?? '');\n }\n }\n}\n\nconst globalRef = (globalThis as unknown as { __yesplz_analytics_rn__?: Analytics });\nexport const analytics: Analytics =\n globalRef.__yesplz_analytics_rn__ ||\n (globalRef.__yesplz_analytics_rn__ = new Analytics());\n","export const VERSION = '0.1.0-rn';\n\nexport const EventType = {\n ViewItemList: 'view_item_list',\n ViewItem: 'yp_product_view',\n ViewProduct: 'yp_product_view',\n SelectItem: 'yp_product_select',\n SelectProduct: 'yp_product_select',\n AddToCart: 'yp_product_cart',\n RemoveFromCart: 'yp_product_remove_from_cart',\n BeginCheckout: 'yp_begin_checkout',\n Purchase: 'yp_product_purchase',\n FavoriteProduct: 'yp_product_favorite',\n UnfavoriteProduct: 'yp_product_unfavorite',\n AddToWishlist: 'yp_product_favorite',\n RemoveFromWishlist: 'yp_product_unfavorite',\n ViewBrand: 'yp_brand_view',\n FavoriteBrand: 'yp_brand_favorite',\n UnfavoriteBrand: 'yp_brand_unfavorite',\n} as const;\n\nexport type EventTypeValue = (typeof EventType)[keyof typeof EventType];\n\nexport const GaEventType: Record<string, string> = {\n [EventType.ViewProduct]: 'view_item',\n [EventType.SelectItem]: 'select_item',\n [EventType.AddToCart]: 'add_to_cart',\n [EventType.RemoveFromCart]: 'remove_from_cart',\n [EventType.BeginCheckout]: 'begin_checkout',\n [EventType.Purchase]: 'purchase',\n [EventType.FavoriteProduct]: 'add_to_wishlist',\n [EventType.UnfavoriteProduct]: 'remove_from_wishlist',\n};\n\nexport const GaEventTypeReverse: Record<string, string> = {\n view_item: EventType.ViewProduct,\n select_item: EventType.SelectItem,\n add_to_cart: EventType.AddToCart,\n remove_from_cart: EventType.RemoveFromCart,\n begin_checkout: EventType.BeginCheckout,\n purchase: EventType.Purchase,\n add_to_wishlist: EventType.FavoriteProduct,\n remove_from_wishlist: EventType.UnfavoriteProduct,\n};\n\nexport const ItemListId = {\n SEARCH_RESULTS: 'search-results',\n PRODUCT_LIST: 'product-list',\n YOU_MAY_ALSO_LIKE: 'you-may-also-like',\n COMPLETE_THE_LOOK: 'complete-the-look',\n COLLABORATIVE_FILTERING: 'collaborative-filtering',\n MORE_FROM_BRAND: 'more-from-brand',\n STYLE_WITH: 'style-with',\n SHOPPING_CART: 'shopping-cart',\n ITEM_FOR_YOU: 'item-for-you',\n BRAND_FOR_YOU: 'brand-for-you',\n} as const;\n\nexport type ItemListIdValue = (typeof ItemListId)[keyof typeof ItemListId];\n\nconst LIST_ID_ALIASES: Record<string, string> = {\n Search: ItemListId.SEARCH_RESULTS,\n 'search-results': ItemListId.SEARCH_RESULTS,\n PLP: ItemListId.PRODUCT_LIST,\n 'product-list': ItemListId.PRODUCT_LIST,\n YMAL: ItemListId.YOU_MAY_ALSO_LIKE,\n 'you-may-also-like': ItemListId.YOU_MAY_ALSO_LIKE,\n CTL: ItemListId.COMPLETE_THE_LOOK,\n 'complete-the-look': ItemListId.COMPLETE_THE_LOOK,\n CF: ItemListId.COLLABORATIVE_FILTERING,\n 'collaborative-filtering': ItemListId.COLLABORATIVE_FILTERING,\n 'frequently-bought-together': ItemListId.COLLABORATIVE_FILTERING,\n Brand: ItemListId.MORE_FROM_BRAND,\n 'more-from-brand': ItemListId.MORE_FROM_BRAND,\n STW: ItemListId.STYLE_WITH,\n 'style-with': ItemListId.STYLE_WITH,\n CART: ItemListId.SHOPPING_CART,\n 'shopping-cart': ItemListId.SHOPPING_CART,\n 'item-for-you': ItemListId.ITEM_FOR_YOU,\n 'brand-for-you': ItemListId.BRAND_FOR_YOU,\n};\n\nexport function normalizeItemListId(input: string | undefined | null): string | undefined | null {\n if (!input) return input;\n const alias = LIST_ID_ALIASES[input];\n if (alias) return alias;\n const canonical = Object.values(ItemListId) as string[];\n if (canonical.includes(input)) return input;\n return input;\n}\n\nexport const API_EVENTS: string[] = [\n EventType.ViewProduct,\n EventType.AddToCart,\n EventType.RemoveFromCart,\n EventType.BeginCheckout,\n EventType.Purchase,\n EventType.FavoriteProduct,\n EventType.UnfavoriteProduct,\n EventType.ViewBrand,\n EventType.FavoriteBrand,\n EventType.UnfavoriteBrand,\n];\n","import AsyncStorage from '@react-native-async-storage/async-storage';\n\nexport const StorageKeys = {\n CID: 'yp_cid',\n SESSION: 'yp_session',\n USER_ID: 'yp_user_id',\n USER_PROPS: 'yp_user_props',\n ATTRIBUTION: 'yp_attribution',\n PENDING_EVENTS: 'yp_pending_events',\n} as const;\n\nexport const Storage = {\n async getItem(key: string): Promise<string | null> {\n try {\n return await AsyncStorage.getItem(key);\n } catch {\n return null;\n }\n },\n async setItem(key: string, value: string): Promise<void> {\n try {\n await AsyncStorage.setItem(key, value);\n } catch {\n // ignore\n }\n },\n async removeItem(key: string): Promise<void> {\n try {\n await AsyncStorage.removeItem(key);\n } catch {\n // ignore\n }\n },\n async getJSON<T>(key: string, fallback: T): Promise<T> {\n const raw = await Storage.getItem(key);\n if (!raw) return fallback;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return fallback;\n }\n },\n async setJSON(key: string, value: unknown): Promise<void> {\n try {\n await Storage.setItem(key, JSON.stringify(value));\n } catch {\n // ignore\n }\n },\n};\n","import { Storage, StorageKeys } from './storage';\n\nexport function generateId(): string {\n return Date.now().toString(36) + Math.random().toString(36).substring(2);\n}\n\nexport function hashCode(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n hash = (hash << 5) - hash + str.charCodeAt(i);\n hash |= 0;\n }\n return hash;\n}\n\nexport function numericSessionId(sessionId: string | null | undefined): number {\n if (!sessionId) return Math.floor(Date.now() / 1000);\n return Math.abs(hashCode(sessionId)) || Math.floor(Date.now() / 1000);\n}\n\nexport interface Identity {\n cid: string;\n sessionId: string;\n userId: string | null;\n userProperties: Record<string, unknown>;\n}\n\nexport async function loadIdentity(): Promise<Identity> {\n const [cidStored, sessionStored, userIdStored, userPropsStored] = await Promise.all([\n Storage.getItem(StorageKeys.CID),\n Storage.getItem(StorageKeys.SESSION),\n Storage.getItem(StorageKeys.USER_ID),\n Storage.getItem(StorageKeys.USER_PROPS),\n ]);\n\n let cid = cidStored;\n if (!cid) {\n cid = generateId();\n await Storage.setItem(StorageKeys.CID, cid);\n }\n\n let sessionId = sessionStored;\n if (!sessionId) {\n sessionId = generateId();\n await Storage.setItem(StorageKeys.SESSION, sessionId);\n }\n\n let userProperties: Record<string, unknown> = {};\n if (userPropsStored) {\n try {\n userProperties = JSON.parse(userPropsStored) as Record<string, unknown>;\n } catch {\n userProperties = {};\n }\n }\n\n return { cid, sessionId, userId: userIdStored, userProperties };\n}\n\nexport async function saveCid(cid: string): Promise<void> {\n await Storage.setItem(StorageKeys.CID, cid);\n}\n\nexport async function saveSession(sessionId: string): Promise<void> {\n await Storage.setItem(StorageKeys.SESSION, sessionId);\n}\n\nexport async function saveUser(\n userId: string,\n userProperties: Record<string, unknown>,\n cacheUserId: boolean\n): Promise<void> {\n if (cacheUserId) {\n await Storage.setItem(StorageKeys.USER_ID, userId);\n }\n await Storage.setJSON(StorageKeys.USER_PROPS, userProperties);\n}\n\nexport async function clearUser(): Promise<void> {\n await Storage.removeItem(StorageKeys.USER_ID);\n await Storage.removeItem(StorageKeys.USER_PROPS);\n}\n","import { Storage, StorageKeys } from './storage';\nimport { EventType, GaEventTypeReverse } from './constants';\nimport type { TrackProperties } from './types';\n\nconst EXPIRY_MS = 30 * 60 * 1000;\n\ntype AttributionRecord = { source: string; ts: number };\ntype AttributionStore = Record<string, AttributionRecord>;\n\nfunction normalizeId(rawId: unknown, idPrefix?: string): string | null {\n if (!rawId) return null;\n const idStr = String(rawId);\n if (idPrefix && idStr.startsWith(idPrefix)) {\n return idStr.slice(idPrefix.length);\n }\n const match = idStr.match(/^[a-zA-Z]+-(.+)$/);\n return match ? match[1] : idStr;\n}\n\nasync function loadStore(): Promise<AttributionStore> {\n return Storage.getJSON<AttributionStore>(StorageKeys.ATTRIBUTION, {});\n}\n\nasync function saveStore(store: AttributionStore): Promise<void> {\n await Storage.setJSON(StorageKeys.ATTRIBUTION, store);\n}\n\nfunction pruneExpired(store: AttributionStore): AttributionStore {\n const now = Date.now();\n const next: AttributionStore = {};\n for (const [k, v] of Object.entries(store)) {\n if (now - v.ts <= EXPIRY_MS) next[k] = v;\n }\n return next;\n}\n\nexport async function handleAttribution(\n eventType: string,\n props: TrackProperties,\n idPrefix?: string\n): Promise<void> {\n const normalizedEventType = GaEventTypeReverse[eventType] || eventType;\n\n if (normalizedEventType === EventType.SelectItem) {\n const itemListId = props.item_list_id;\n const rawId = props.id ?? props.items?.[0]?.item_id;\n const productId = normalizeId(rawId, idPrefix);\n if (itemListId && productId) {\n let store = await loadStore();\n store = pruneExpired(store);\n store[productId] = { source: itemListId, ts: Date.now() };\n await saveStore(store);\n }\n return;\n }\n\n if (normalizedEventType === EventType.ViewProduct) {\n const rawId = props.id ?? props.items?.[0]?.item_id;\n const productId = normalizeId(rawId, idPrefix);\n if (!productId) return;\n const store = await loadStore();\n const entry = store[productId];\n if (entry && Date.now() - entry.ts <= EXPIRY_MS) {\n props.item_list_id = entry.source;\n if (Array.isArray(props.items)) {\n props.items = props.items.map((item) => ({ ...item, item_list_id: entry.source }));\n }\n }\n return;\n }\n\n if (normalizedEventType === EventType.AddToCart) {\n if (!Array.isArray(props.items)) return;\n const store = await loadStore();\n props.items = props.items.map((item) => {\n const productId = normalizeId(item.item_id, idPrefix);\n const entry = productId ? store[productId] : null;\n if (entry && Date.now() - entry.ts <= EXPIRY_MS) {\n return { ...item, item_list_id: entry.source };\n }\n return item;\n });\n const firstMatch = props.items.find((item) => item.item_list_id);\n if (firstMatch?.item_list_id) {\n props.item_list_id = firstMatch.item_list_id;\n }\n }\n}\n\nexport async function getAttribution(productId: string): Promise<string | null> {\n const store = await loadStore();\n const entry = store[String(productId)];\n if (entry && Date.now() - entry.ts < EXPIRY_MS) return entry.source;\n return null;\n}\n","import { GaEventType } from './constants';\nimport type { TrackProperties } from './types';\n\nfunction toSnakeCase(str: string): string {\n return str.replace(/-/g, '_');\n}\n\nexport interface GaSendOptions {\n gaProxyUrl: string;\n clientId: string;\n sessionId: string;\n numericSessionId: number;\n userId?: string | null;\n debug?: boolean;\n}\n\nexport async function sendToGA(\n eventType: string,\n props: TrackProperties,\n options: GaSendOptions\n): Promise<void> {\n const gaEvent = GaEventType[eventType] || toSnakeCase(eventType);\n const {\n items,\n currency,\n value,\n transaction_id,\n tax,\n shipping,\n coupon,\n ...rest\n } = props;\n\n const params: Record<string, unknown> = {\n session_id: options.numericSessionId,\n engagement_time_msec: 1,\n session_engaged: '1',\n };\n\n if (currency) params.currency = currency;\n if (value !== undefined) params.value = value;\n if (transaction_id) params.transaction_id = transaction_id;\n if (tax !== undefined) params.tax = tax;\n if (shipping !== undefined) params.shipping = shipping;\n if (coupon) params.coupon = coupon;\n if (items) params.items = items;\n\n const passthroughKeys = [\n 'item_list_id',\n 'data_provider',\n 'event_source',\n 'id',\n 'search_term',\n 'total',\n 'total_text',\n 'total_vector',\n 'page_location',\n 'page_title',\n 'page_referrer',\n 'language',\n 'test_marker',\n 'yp_platform',\n 'yp_platform_version',\n 'yp_user_agent',\n ];\n for (const key of passthroughKeys) {\n if (rest[key] !== undefined) params[key] = rest[key];\n }\n\n const body: Record<string, unknown> = {\n client_id: options.clientId || options.sessionId,\n timestamp_micros: Date.now() * 1000,\n events: [{ name: gaEvent, params }],\n };\n\n if (options.userId) body.user_id = options.userId;\n\n const sep = options.gaProxyUrl.includes('?') ? '&' : '?';\n const url = options.debug\n ? `${options.gaProxyUrl}${sep}debug=1`\n : options.gaProxyUrl;\n\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n if (options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] GA MP → ${gaEvent} (status ${res.status})`);\n }\n } catch (e) {\n if (options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] GA MP error: ${(e as Error).message}`);\n }\n }\n}\n","import { Storage, StorageKeys } from './storage';\nimport type { ApiEvent } from './types';\n\nexport interface BeaconOptions {\n apiEndpoint: string;\n apiToken?: string | null;\n defaultParams?: Record<string, unknown>;\n idPrefix?: string;\n debounceMs?: number;\n debug?: boolean;\n}\n\nexport class Beacon {\n private queue: ApiEvent[] = [];\n private isSending = false;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(private options: BeaconOptions) {}\n\n enqueue(event: ApiEvent): void {\n this.queue.push(event);\n this.scheduleSend();\n }\n\n enqueueAll(events: ApiEvent[]): void {\n this.queue.push(...events);\n this.scheduleSend();\n }\n\n private scheduleSend(): void {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(() => {\n void this.send();\n }, this.options.debounceMs ?? 1000);\n }\n\n async send(retryCount = 0): Promise<void> {\n if (this.queue.length === 0) return;\n if (!this.options.apiEndpoint) return;\n if (this.isSending) return;\n\n this.isSending = true;\n const eventsToSend = this.queue.splice(0, this.queue.length);\n\n const events = eventsToSend.map((event) => {\n const merged: Record<string, unknown> = {\n ...event,\n ...(this.options.defaultParams ?? {}),\n };\n const rawId = (event.extra_data as Record<string, unknown>).id;\n if (rawId && this.options.idPrefix) {\n merged.extra_data = {\n ...event.extra_data,\n id: `${this.options.idPrefix}${rawId}`,\n };\n }\n return merged;\n });\n\n try {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.options.apiToken) headers.Authorization = `Token ${this.options.apiToken}`;\n\n const res = await fetch(this.options.apiEndpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify(events),\n });\n\n if (res.status > 299) {\n throw new Error(`Failed to send events (status ${res.status})`);\n }\n\n if (this.options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] Sync: ${events.length} events sent`);\n }\n await Storage.removeItem(StorageKeys.PENDING_EVENTS);\n } catch (e) {\n if (this.options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] Sync failed: ${(e as Error).message}`);\n }\n this.queue.unshift(...eventsToSend);\n this.isSending = false;\n if (retryCount < 1) {\n setTimeout(() => void this.send(retryCount + 1), 2000);\n }\n return;\n }\n\n this.isSending = false;\n if (this.queue.length > 0) this.scheduleSend();\n }\n\n async flush(): Promise<void> {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n await this.send();\n }\n\n async savePending(): Promise<void> {\n if (this.queue.length === 0) return;\n const toSave = this.queue.slice(-100);\n await Storage.setJSON(StorageKeys.PENDING_EVENTS, toSave);\n this.queue = [];\n }\n\n async restorePending(): Promise<void> {\n const pending = await Storage.getJSON<ApiEvent[]>(StorageKeys.PENDING_EVENTS, []);\n if (pending.length > 0) {\n this.queue.unshift(...pending);\n await Storage.removeItem(StorageKeys.PENDING_EVENTS);\n this.scheduleSend();\n }\n }\n}\n"],"mappings":"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","names":["AsyncStorage"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/analytics.ts","../src/constants.ts","../src/storage.ts","../src/ids.ts","../src/attribution.ts","../src/ga.ts","../src/beacon.ts"],"sourcesContent":["export { analytics, Analytics } from './analytics';\nexport {\n EventType,\n ItemListId,\n normalizeItemListId,\n VERSION,\n} from './constants';\nexport type {\n EventTypeValue,\n ItemListIdValue,\n} from './constants';\nexport type {\n AnalyticsConfig,\n TrackItem,\n TrackProperties,\n ApiEvent,\n EventMetadata,\n} from './types';\n","import { Platform, AppState, type AppStateStatus } from 'react-native';\nimport {\n API_EVENTS,\n EventType,\n GaEventType,\n GaEventTypeReverse,\n normalizeItemListId,\n VERSION,\n} from './constants';\nimport { Storage, StorageKeys } from './storage';\nimport {\n generateId,\n loadIdentity,\n numericSessionId,\n saveSession,\n saveUser,\n clearUser as clearUserStorage,\n} from './ids';\nimport { handleAttribution } from './attribution';\nimport { sendToGA } from './ga';\nimport { Beacon } from './beacon';\nimport type {\n AnalyticsConfig,\n ApiEvent,\n EventMetadata,\n TrackProperties,\n} from './types';\n\nconst DEFAULT_DEBOUNCE_MS = 1000;\nconst DEFAULT_API_BASE_URL = 'https://api.yesplz.ai';\nconst DEFAULT_GA_PROXY_BASE_URL = 'https://ypsh-admin.yesplz.ai/api/mp/collect';\n\nfunction buildUserAgent(): string {\n const os = Platform.OS;\n const version = Platform.Version;\n return `YesPlzSDK-RN/${VERSION} (${os}; ${String(version)})`;\n}\n\nexport class Analytics {\n private config: Required<\n Pick<AnalyticsConfig, 'debug' | 'debounceMs' | 'cacheUserId' | 'idPrefix'>\n > &\n Omit<AnalyticsConfig, 'debug' | 'debounceMs' | 'cacheUserId' | 'idPrefix'> & {\n appId?: string;\n gaProxyUrl?: string;\n } = {\n debug: false,\n debounceMs: DEFAULT_DEBOUNCE_MS,\n cacheUserId: true,\n idPrefix: '',\n };\n\n private cid: string | null = null;\n private sessionId: string | null = null;\n private userId: string | null = null;\n private userProperties: Record<string, unknown> = {};\n private isInitialized = false;\n private initPromise: Promise<void> | null = null;\n private beacon: Beacon | null = null;\n private pendingTracks: { eventType: string; properties: TrackProperties }[] = [];\n private appStateSubscription: { remove(): void } | null = null;\n\n init(appId: string, config: AnalyticsConfig = {}): Analytics {\n if (this.isInitialized || this.initPromise) return this;\n this.initPromise = this.initInternal(appId, config);\n void this.initPromise;\n return this;\n }\n\n ready(): Promise<void> {\n return this.initPromise ?? Promise.resolve();\n }\n\n private async initInternal(appId: string, config: AnalyticsConfig): Promise<void> {\n const normalizedAppId = String(appId).trim();\n if (!normalizedAppId) {\n throw new Error('[YesPlz Analytics] appId must be a non-empty string');\n }\n\n const apiBaseUrl = (config.apiBaseUrl || DEFAULT_API_BASE_URL).replace(/\\/$/, '');\n const apiEndpoint =\n config.apiEndpoint ||\n `${apiBaseUrl}/api/v1/retailer/${encodeURIComponent(normalizedAppId)}/interactions/`;\n const gaProxyBaseUrl = config.gaProxyBaseUrl || DEFAULT_GA_PROXY_BASE_URL;\n const gaProxySep = gaProxyBaseUrl.includes('?') ? '&' : '?';\n const gaProxyUrl = `${gaProxyBaseUrl}${gaProxySep}shop=${encodeURIComponent(normalizedAppId)}`;\n\n const mergedDefaultParams: Record<string, unknown> = {\n ...(config.defaultParams || {}),\n };\n if (config.testMarker) {\n mergedDefaultParams.test_marker = config.testMarker;\n }\n\n this.config = {\n ...this.config,\n appId: normalizedAppId,\n apiEndpoint,\n apiBaseUrl,\n apiToken: config.apiToken ?? null,\n gaProxyBaseUrl,\n gaProxyUrl,\n idPrefix: config.idPrefix || '',\n defaultParams: mergedDefaultParams,\n testMarker: config.testMarker,\n debug: config.debug ?? false,\n cacheUserId: config.cacheUserId ?? true,\n debounceMs: config.debounceMs || DEFAULT_DEBOUNCE_MS,\n };\n\n const identity = await loadIdentity();\n this.cid = identity.cid;\n this.sessionId = identity.sessionId;\n this.userId = identity.userId;\n this.userProperties = identity.userProperties;\n\n if (config.userId) {\n await this.setUserInternal(config.userId, config.userProperties || {});\n }\n\n if (apiEndpoint) {\n this.beacon = new Beacon({\n apiEndpoint,\n apiToken: this.config.apiToken,\n defaultParams: this.config.defaultParams,\n idPrefix: this.config.idPrefix,\n debounceMs: this.config.debounceMs,\n debug: this.config.debug,\n });\n await this.beacon.restorePending();\n }\n\n this.appStateSubscription = AppState.addEventListener(\n 'change',\n (state: AppStateStatus) => {\n if (state === 'background' || state === 'inactive') {\n void this.beacon?.savePending();\n }\n }\n );\n\n this.isInitialized = true;\n this.log('Initialized');\n\n const queued = this.pendingTracks.splice(0, this.pendingTracks.length);\n for (const item of queued) {\n void this.dispatchTrack(item.eventType, item.properties);\n }\n }\n\n async setUser(\n userId: string | null,\n userProperties: Record<string, unknown> = {}\n ): Promise<Analytics> {\n await this.ready();\n if (userId === null) {\n this.userId = null;\n this.userProperties = {};\n await clearUserStorage();\n this.log('User cleared');\n return this;\n }\n await this.setUserInternal(userId, userProperties);\n return this;\n }\n\n private async setUserInternal(\n userId: string,\n userProperties: Record<string, unknown>\n ): Promise<void> {\n const id = String(userId);\n if (id.length === 0) {\n // eslint-disable-next-line no-console\n console.error('[YesPlz Analytics] User ID must be a non-empty value');\n return;\n }\n this.userId = id;\n this.userProperties = JSON.parse(JSON.stringify(userProperties));\n await saveUser(this.userId, this.userProperties, this.config.cacheUserId);\n this.log(`User set: ${id}`);\n }\n\n getUser(): { userId: string; userProperties: Record<string, unknown> } | null {\n if (!this.userId) return null;\n return { userId: this.userId, userProperties: this.userProperties };\n }\n\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n getClientId(): string | null {\n return this.cid;\n }\n\n track(eventType: string, properties: TrackProperties = {}): Analytics {\n if (typeof eventType !== 'string' || eventType.length === 0) {\n // eslint-disable-next-line no-console\n console.error('[YesPlz Analytics] Event type must be a non-empty string');\n return this;\n }\n\n if (!this.isInitialized) {\n this.pendingTracks.push({\n eventType,\n properties: JSON.parse(JSON.stringify(properties)),\n });\n return this;\n }\n\n void this.dispatchTrack(eventType, properties);\n return this;\n }\n\n private async dispatchTrack(\n eventType: string,\n properties: TrackProperties\n ): Promise<void> {\n const props: TrackProperties = JSON.parse(JSON.stringify(properties));\n\n await handleAttribution(eventType, props, this.config.idPrefix);\n\n if (eventType === EventType.Purchase && !props.transaction_id) {\n props.transaction_id = generateId();\n }\n\n if (props.id && !Array.isArray(props.items)) {\n props.items = [{ item_id: props.id, ...(props as Record<string, unknown>) }];\n }\n\n if (props.item_list_id) {\n props.item_list_id = normalizeItemListId(props.item_list_id) || undefined;\n }\n if (Array.isArray(props.items)) {\n props.items = props.items.map((item) =>\n item.item_list_id ? { ...item, item_list_id: normalizeItemListId(item.item_list_id) || undefined } : item\n );\n }\n\n const metadata = this.collectMetadata();\n Object.assign(props, metadata);\n props.data_provider = 'yesplz';\n if (this.config.testMarker) {\n props.test_marker = this.config.testMarker;\n }\n\n await this.sendGA(eventType, props);\n\n const apiEventType = GaEventTypeReverse[eventType] || eventType;\n if (API_EVENTS.includes(apiEventType)) {\n this.queueApi(apiEventType, props, metadata);\n }\n }\n\n private async sendGA(eventType: string, props: TrackProperties): Promise<void> {\n if (!this.config.gaProxyUrl) return;\n if (!this.cid || !this.sessionId) return;\n\n const gaEventName = GaEventType[eventType] ?? eventType;\n await sendToGA(eventType, props, {\n gaProxyUrl: this.config.gaProxyUrl,\n clientId: this.cid,\n sessionId: this.sessionId,\n numericSessionId: numericSessionId(this.sessionId),\n userId: this.userId,\n debug: this.config.debug,\n });\n this.log(`Track: ${gaEventName}`, props.items?.length ? { items: props.items.length } : undefined);\n }\n\n private queueApi(\n eventType: string,\n props: TrackProperties,\n metadata: EventMetadata\n ): void {\n if (!this.beacon) return;\n const items = props.items && props.items.length > 0 ? props.items : [props];\n const fallbackUrl = `app://${this.config.appId ?? 'yesplz'}/`;\n const url =\n typeof props.page_location === 'string' && props.page_location.length > 0\n ? props.page_location\n : fallbackUrl;\n const referrerUrl =\n typeof props.page_referrer === 'string' && props.page_referrer.length > 0\n ? props.page_referrer\n : null;\n\n const events: ApiEvent[] = items.map((item) => {\n const merged: Record<string, unknown> = {\n ...(props as Record<string, unknown>),\n ...(item as Record<string, unknown>),\n ...metadata,\n };\n const itemId = (item as { item_id?: string }).item_id;\n if (itemId) merged.id = itemId;\n merged.identifier_type = eventType.startsWith('yp_brand_')\n ? 'brand_name'\n : 'product_id';\n\n const event: ApiEvent = {\n event_type: eventType,\n url,\n referrer_url: referrerUrl,\n user_id: this.userId,\n session_id: this.sessionId,\n extra_data: merged,\n };\n if (Object.keys(this.userProperties).length > 0) {\n event.extra_user_data = this.userProperties;\n }\n return event;\n });\n\n this.beacon.enqueueAll(events);\n }\n\n private collectMetadata(): EventMetadata {\n const metadata: EventMetadata = {\n yp_client_time: Date.now(),\n yp_platform: Platform.OS,\n yp_platform_version: String(Platform.Version),\n yp_user_agent: buildUserAgent(),\n yp_timezone_offset: new Date().getTimezoneOffset(),\n };\n try {\n metadata.yp_timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n // ignore\n }\n if (this.cid) metadata.google_client_id = this.cid;\n return metadata;\n }\n\n async flush(): Promise<Analytics> {\n await this.ready();\n await this.beacon?.flush();\n return this;\n }\n\n async reset(): Promise<Analytics> {\n await this.ready();\n this.userId = null;\n this.userProperties = {};\n await clearUserStorage();\n await Storage.removeItem(StorageKeys.PENDING_EVENTS);\n await Storage.removeItem(StorageKeys.ATTRIBUTION);\n const newSession = generateId();\n this.sessionId = newSession;\n await saveSession(newSession);\n this.log('Reset');\n return this;\n }\n\n teardown(): void {\n this.appStateSubscription?.remove();\n this.appStateSubscription = null;\n }\n\n private log(message: string, data?: unknown): void {\n if (this.config.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] ${message}`, data ?? '');\n }\n }\n}\n\nconst globalRef = (globalThis as unknown as { __yesplz_analytics_rn__?: Analytics });\nexport const analytics: Analytics =\n globalRef.__yesplz_analytics_rn__ ||\n (globalRef.__yesplz_analytics_rn__ = new Analytics());\n","export const VERSION = '0.1.0-rn';\n\nexport const EventType = {\n ViewItemList: 'view_item_list',\n ViewItem: 'yp_product_view',\n ViewProduct: 'yp_product_view',\n SelectItem: 'yp_product_select',\n SelectProduct: 'yp_product_select',\n AddToCart: 'yp_product_cart',\n RemoveFromCart: 'yp_product_remove_from_cart',\n BeginCheckout: 'yp_begin_checkout',\n Purchase: 'yp_product_purchase',\n FavoriteProduct: 'yp_product_favorite',\n UnfavoriteProduct: 'yp_product_unfavorite',\n AddToWishlist: 'yp_product_favorite',\n RemoveFromWishlist: 'yp_product_unfavorite',\n ViewBrand: 'yp_brand_view',\n FavoriteBrand: 'yp_brand_favorite',\n UnfavoriteBrand: 'yp_brand_unfavorite',\n} as const;\n\nexport type EventTypeValue = (typeof EventType)[keyof typeof EventType];\n\nexport const GaEventType: Record<string, string> = {\n [EventType.ViewProduct]: 'view_item',\n [EventType.SelectItem]: 'select_item',\n [EventType.AddToCart]: 'add_to_cart',\n [EventType.RemoveFromCart]: 'remove_from_cart',\n [EventType.BeginCheckout]: 'begin_checkout',\n [EventType.Purchase]: 'purchase',\n [EventType.FavoriteProduct]: 'add_to_wishlist',\n [EventType.UnfavoriteProduct]: 'remove_from_wishlist',\n};\n\nexport const GaEventTypeReverse: Record<string, string> = {\n view_item: EventType.ViewProduct,\n select_item: EventType.SelectItem,\n add_to_cart: EventType.AddToCart,\n remove_from_cart: EventType.RemoveFromCart,\n begin_checkout: EventType.BeginCheckout,\n purchase: EventType.Purchase,\n add_to_wishlist: EventType.FavoriteProduct,\n remove_from_wishlist: EventType.UnfavoriteProduct,\n};\n\nexport const ItemListId = {\n SEARCH_RESULTS: 'search_results',\n PRODUCT_LIST: 'category',\n YOU_MAY_ALSO_LIKE: 'rec_YMAL',\n COMPLETE_THE_LOOK: 'rec_CTL',\n COLLABORATIVE_FILTERING: 'rec_CF',\n MORE_FROM_BRAND: 'rec_Brand',\n STYLE_WITH: 'STW',\n SHOPPING_CART: 'rec_CART',\n ITEM_FOR_YOU: 'item-for-you',\n BRAND_FOR_YOU: 'brand-for-you',\n} as const;\n\nexport type ItemListIdValue = (typeof ItemListId)[keyof typeof ItemListId];\n\nconst LIST_ID_ALIASES: Record<string, string> = {\n Search: ItemListId.SEARCH_RESULTS,\n search_results: ItemListId.SEARCH_RESULTS,\n 'search-results': ItemListId.SEARCH_RESULTS,\n PLP: ItemListId.PRODUCT_LIST,\n category: ItemListId.PRODUCT_LIST,\n 'product-list': ItemListId.PRODUCT_LIST,\n YMAL: ItemListId.YOU_MAY_ALSO_LIKE,\n rec_YMAL: ItemListId.YOU_MAY_ALSO_LIKE,\n 'you-may-also-like': ItemListId.YOU_MAY_ALSO_LIKE,\n CTL: ItemListId.COMPLETE_THE_LOOK,\n rec_CTL: ItemListId.COMPLETE_THE_LOOK,\n 'complete-the-look': ItemListId.COMPLETE_THE_LOOK,\n CF: ItemListId.COLLABORATIVE_FILTERING,\n rec_CF: ItemListId.COLLABORATIVE_FILTERING,\n 'collaborative-filtering': ItemListId.COLLABORATIVE_FILTERING,\n 'frequently-bought-together': ItemListId.COLLABORATIVE_FILTERING,\n Brand: ItemListId.MORE_FROM_BRAND,\n rec_Brand: ItemListId.MORE_FROM_BRAND,\n 'more-from-brand': ItemListId.MORE_FROM_BRAND,\n STW: ItemListId.STYLE_WITH,\n 'style-with': ItemListId.STYLE_WITH,\n CART: ItemListId.SHOPPING_CART,\n rec_CART: ItemListId.SHOPPING_CART,\n 'shopping-cart': ItemListId.SHOPPING_CART,\n 'item-for-you': ItemListId.ITEM_FOR_YOU,\n 'brand-for-you': ItemListId.BRAND_FOR_YOU,\n};\n\nexport function normalizeItemListId(input: string | undefined | null): string | undefined | null {\n if (!input) return input;\n const alias = LIST_ID_ALIASES[input];\n if (alias) return alias;\n const canonical = Object.values(ItemListId) as string[];\n if (canonical.includes(input)) return input;\n return input;\n}\n\nexport const API_EVENTS: string[] = [\n EventType.ViewProduct,\n EventType.AddToCart,\n EventType.RemoveFromCart,\n EventType.BeginCheckout,\n EventType.Purchase,\n EventType.FavoriteProduct,\n EventType.UnfavoriteProduct,\n EventType.ViewBrand,\n EventType.FavoriteBrand,\n EventType.UnfavoriteBrand,\n];\n","import AsyncStorage from '@react-native-async-storage/async-storage';\n\nexport const StorageKeys = {\n CID: 'yp_cid',\n SESSION: 'yp_session',\n USER_ID: 'yp_user_id',\n USER_PROPS: 'yp_user_props',\n ATTRIBUTION: 'yp_attribution',\n PENDING_EVENTS: 'yp_pending_events',\n} as const;\n\nexport const Storage = {\n async getItem(key: string): Promise<string | null> {\n try {\n return await AsyncStorage.getItem(key);\n } catch {\n return null;\n }\n },\n async setItem(key: string, value: string): Promise<void> {\n try {\n await AsyncStorage.setItem(key, value);\n } catch {\n // ignore\n }\n },\n async removeItem(key: string): Promise<void> {\n try {\n await AsyncStorage.removeItem(key);\n } catch {\n // ignore\n }\n },\n async getJSON<T>(key: string, fallback: T): Promise<T> {\n const raw = await Storage.getItem(key);\n if (!raw) return fallback;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return fallback;\n }\n },\n async setJSON(key: string, value: unknown): Promise<void> {\n try {\n await Storage.setItem(key, JSON.stringify(value));\n } catch {\n // ignore\n }\n },\n};\n","import { Storage, StorageKeys } from './storage';\n\nexport function generateId(): string {\n return Date.now().toString(36) + Math.random().toString(36).substring(2);\n}\n\nexport function hashCode(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n hash = (hash << 5) - hash + str.charCodeAt(i);\n hash |= 0;\n }\n return hash;\n}\n\nexport function numericSessionId(sessionId: string | null | undefined): number {\n if (!sessionId) return Math.floor(Date.now() / 1000);\n return Math.abs(hashCode(sessionId)) || Math.floor(Date.now() / 1000);\n}\n\nexport interface Identity {\n cid: string;\n sessionId: string;\n userId: string | null;\n userProperties: Record<string, unknown>;\n}\n\nexport async function loadIdentity(): Promise<Identity> {\n const [cidStored, sessionStored, userIdStored, userPropsStored] = await Promise.all([\n Storage.getItem(StorageKeys.CID),\n Storage.getItem(StorageKeys.SESSION),\n Storage.getItem(StorageKeys.USER_ID),\n Storage.getItem(StorageKeys.USER_PROPS),\n ]);\n\n let cid = cidStored;\n if (!cid) {\n cid = generateId();\n await Storage.setItem(StorageKeys.CID, cid);\n }\n\n let sessionId = sessionStored;\n if (!sessionId) {\n sessionId = generateId();\n await Storage.setItem(StorageKeys.SESSION, sessionId);\n }\n\n let userProperties: Record<string, unknown> = {};\n if (userPropsStored) {\n try {\n userProperties = JSON.parse(userPropsStored) as Record<string, unknown>;\n } catch {\n userProperties = {};\n }\n }\n\n return { cid, sessionId, userId: userIdStored, userProperties };\n}\n\nexport async function saveCid(cid: string): Promise<void> {\n await Storage.setItem(StorageKeys.CID, cid);\n}\n\nexport async function saveSession(sessionId: string): Promise<void> {\n await Storage.setItem(StorageKeys.SESSION, sessionId);\n}\n\nexport async function saveUser(\n userId: string,\n userProperties: Record<string, unknown>,\n cacheUserId: boolean\n): Promise<void> {\n if (cacheUserId) {\n await Storage.setItem(StorageKeys.USER_ID, userId);\n }\n await Storage.setJSON(StorageKeys.USER_PROPS, userProperties);\n}\n\nexport async function clearUser(): Promise<void> {\n await Storage.removeItem(StorageKeys.USER_ID);\n await Storage.removeItem(StorageKeys.USER_PROPS);\n}\n","import { Storage, StorageKeys } from './storage';\nimport { EventType, GaEventTypeReverse } from './constants';\nimport type { TrackProperties } from './types';\n\nconst EXPIRY_MS = 30 * 60 * 1000;\n\ntype AttributionRecord = { source: string; ts: number };\ntype AttributionStore = Record<string, AttributionRecord>;\n\nfunction normalizeId(rawId: unknown, idPrefix?: string): string | null {\n if (!rawId) return null;\n const idStr = String(rawId);\n if (idPrefix && idStr.startsWith(idPrefix)) {\n return idStr.slice(idPrefix.length);\n }\n const match = idStr.match(/^[a-zA-Z]+-(.+)$/);\n return match ? match[1] : idStr;\n}\n\nasync function loadStore(): Promise<AttributionStore> {\n return Storage.getJSON<AttributionStore>(StorageKeys.ATTRIBUTION, {});\n}\n\nasync function saveStore(store: AttributionStore): Promise<void> {\n await Storage.setJSON(StorageKeys.ATTRIBUTION, store);\n}\n\nfunction pruneExpired(store: AttributionStore): AttributionStore {\n const now = Date.now();\n const next: AttributionStore = {};\n for (const [k, v] of Object.entries(store)) {\n if (now - v.ts <= EXPIRY_MS) next[k] = v;\n }\n return next;\n}\n\nexport async function handleAttribution(\n eventType: string,\n props: TrackProperties,\n idPrefix?: string\n): Promise<void> {\n const normalizedEventType = GaEventTypeReverse[eventType] || eventType;\n\n if (normalizedEventType === EventType.SelectItem) {\n const itemListId = props.item_list_id;\n const rawId = props.id ?? props.items?.[0]?.item_id;\n const productId = normalizeId(rawId, idPrefix);\n if (itemListId && productId) {\n let store = await loadStore();\n store = pruneExpired(store);\n store[productId] = { source: itemListId, ts: Date.now() };\n await saveStore(store);\n }\n return;\n }\n\n if (normalizedEventType === EventType.ViewProduct) {\n const rawId = props.id ?? props.items?.[0]?.item_id;\n const productId = normalizeId(rawId, idPrefix);\n if (!productId) return;\n const store = await loadStore();\n const entry = store[productId];\n if (entry && Date.now() - entry.ts <= EXPIRY_MS) {\n props.item_list_id = entry.source;\n if (Array.isArray(props.items)) {\n props.items = props.items.map((item) => ({ ...item, item_list_id: entry.source }));\n }\n }\n return;\n }\n\n if (normalizedEventType === EventType.AddToCart) {\n if (!Array.isArray(props.items)) return;\n const store = await loadStore();\n props.items = props.items.map((item) => {\n const productId = normalizeId(item.item_id, idPrefix);\n const entry = productId ? store[productId] : null;\n if (entry && Date.now() - entry.ts <= EXPIRY_MS) {\n return { ...item, item_list_id: entry.source };\n }\n return item;\n });\n const firstMatch = props.items.find((item) => item.item_list_id);\n if (firstMatch?.item_list_id) {\n props.item_list_id = firstMatch.item_list_id;\n }\n }\n}\n\nexport async function getAttribution(productId: string): Promise<string | null> {\n const store = await loadStore();\n const entry = store[String(productId)];\n if (entry && Date.now() - entry.ts < EXPIRY_MS) return entry.source;\n return null;\n}\n","import { GaEventType } from './constants';\nimport type { TrackProperties } from './types';\n\nfunction toSnakeCase(str: string): string {\n return str.replace(/-/g, '_');\n}\n\nexport interface GaSendOptions {\n gaProxyUrl: string;\n clientId: string;\n sessionId: string;\n numericSessionId: number;\n userId?: string | null;\n debug?: boolean;\n}\n\nexport async function sendToGA(\n eventType: string,\n props: TrackProperties,\n options: GaSendOptions\n): Promise<void> {\n const gaEvent = GaEventType[eventType] || toSnakeCase(eventType);\n const {\n items,\n currency,\n value,\n transaction_id,\n tax,\n shipping,\n coupon,\n ...rest\n } = props;\n\n const params: Record<string, unknown> = {\n session_id: options.numericSessionId,\n engagement_time_msec: 1,\n session_engaged: '1',\n };\n if (options.debug) params.debug_mode = true;\n\n if (currency) params.currency = currency;\n if (value !== undefined) params.value = value;\n if (transaction_id) params.transaction_id = transaction_id;\n if (tax !== undefined) params.tax = tax;\n if (shipping !== undefined) params.shipping = shipping;\n if (coupon) params.coupon = coupon;\n if (items) params.items = items;\n\n const passthroughKeys = [\n 'item_list_id',\n 'data_provider',\n 'event_source',\n 'id',\n 'search_term',\n 'total',\n 'total_text',\n 'total_vector',\n 'page_location',\n 'page_title',\n 'page_referrer',\n 'language',\n 'test_marker',\n 'yp_platform',\n 'yp_platform_version',\n 'yp_user_agent',\n ];\n for (const key of passthroughKeys) {\n if (rest[key] !== undefined) params[key] = rest[key];\n }\n\n const body: Record<string, unknown> = {\n client_id: options.clientId || options.sessionId,\n timestamp_micros: Date.now() * 1000,\n events: [{ name: gaEvent, params }],\n };\n\n if (options.userId) body.user_id = options.userId;\n\n const sep = options.gaProxyUrl.includes('?') ? '&' : '?';\n const url = options.debug\n ? `${options.gaProxyUrl}${sep}debug=1`\n : options.gaProxyUrl;\n\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n if (options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] GA MP → ${gaEvent} (status ${res.status})`);\n }\n } catch (e) {\n if (options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] GA MP error: ${(e as Error).message}`);\n }\n }\n}\n","import { Storage, StorageKeys } from './storage';\nimport type { ApiEvent } from './types';\n\nexport interface BeaconOptions {\n apiEndpoint: string;\n apiToken?: string | null;\n defaultParams?: Record<string, unknown>;\n idPrefix?: string;\n debounceMs?: number;\n debug?: boolean;\n}\n\nexport class Beacon {\n private queue: ApiEvent[] = [];\n private isSending = false;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(private options: BeaconOptions) {}\n\n enqueue(event: ApiEvent): void {\n this.queue.push(event);\n this.scheduleSend();\n }\n\n enqueueAll(events: ApiEvent[]): void {\n this.queue.push(...events);\n this.scheduleSend();\n }\n\n private scheduleSend(): void {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(() => {\n void this.send();\n }, this.options.debounceMs ?? 1000);\n }\n\n async send(retryCount = 0): Promise<void> {\n if (this.queue.length === 0) return;\n if (!this.options.apiEndpoint) return;\n if (this.isSending) return;\n\n this.isSending = true;\n const eventsToSend = this.queue.splice(0, this.queue.length);\n\n const events = eventsToSend.map((event) => {\n const merged: Record<string, unknown> = {\n ...event,\n ...(this.options.defaultParams ?? {}),\n };\n const rawId = (event.extra_data as Record<string, unknown>).id;\n if (rawId && this.options.idPrefix) {\n merged.extra_data = {\n ...event.extra_data,\n id: `${this.options.idPrefix}${rawId}`,\n };\n }\n return merged;\n });\n\n try {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.options.apiToken) headers.Authorization = `Token ${this.options.apiToken}`;\n\n const res = await fetch(this.options.apiEndpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify(events),\n });\n\n if (res.status > 299) {\n throw new Error(`Failed to send events (status ${res.status})`);\n }\n\n if (this.options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] Sync: ${events.length} events sent`);\n }\n await Storage.removeItem(StorageKeys.PENDING_EVENTS);\n } catch (e) {\n if (this.options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] Sync failed: ${(e as Error).message}`);\n }\n this.queue.unshift(...eventsToSend);\n this.isSending = false;\n if (retryCount < 1) {\n setTimeout(() => void this.send(retryCount + 1), 2000);\n }\n return;\n }\n\n this.isSending = false;\n if (this.queue.length > 0) this.scheduleSend();\n }\n\n async flush(): Promise<void> {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n await this.send();\n }\n\n async savePending(): Promise<void> {\n if (this.queue.length === 0) return;\n const toSave = this.queue.slice(-100);\n await Storage.setJSON(StorageKeys.PENDING_EVENTS, toSave);\n this.queue = [];\n }\n\n async restorePending(): Promise<void> {\n const pending = await Storage.getJSON<ApiEvent[]>(StorageKeys.PENDING_EVENTS, []);\n if (pending.length > 0) {\n this.queue.unshift(...pending);\n await Storage.removeItem(StorageKeys.PENDING_EVENTS);\n this.scheduleSend();\n }\n }\n}\n"],"mappings":"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","names":["AsyncStorage"]}
package/dist/index.d.cts CHANGED
@@ -113,14 +113,14 @@ declare const EventType: {
113
113
  };
114
114
  type EventTypeValue = (typeof EventType)[keyof typeof EventType];
115
115
  declare const ItemListId: {
116
- readonly SEARCH_RESULTS: "search-results";
117
- readonly PRODUCT_LIST: "product-list";
118
- readonly YOU_MAY_ALSO_LIKE: "you-may-also-like";
119
- readonly COMPLETE_THE_LOOK: "complete-the-look";
120
- readonly COLLABORATIVE_FILTERING: "collaborative-filtering";
121
- readonly MORE_FROM_BRAND: "more-from-brand";
122
- readonly STYLE_WITH: "style-with";
123
- readonly SHOPPING_CART: "shopping-cart";
116
+ readonly SEARCH_RESULTS: "search_results";
117
+ readonly PRODUCT_LIST: "category";
118
+ readonly YOU_MAY_ALSO_LIKE: "rec_YMAL";
119
+ readonly COMPLETE_THE_LOOK: "rec_CTL";
120
+ readonly COLLABORATIVE_FILTERING: "rec_CF";
121
+ readonly MORE_FROM_BRAND: "rec_Brand";
122
+ readonly STYLE_WITH: "STW";
123
+ readonly SHOPPING_CART: "rec_CART";
124
124
  readonly ITEM_FOR_YOU: "item-for-you";
125
125
  readonly BRAND_FOR_YOU: "brand-for-you";
126
126
  };
package/dist/index.d.ts CHANGED
@@ -113,14 +113,14 @@ declare const EventType: {
113
113
  };
114
114
  type EventTypeValue = (typeof EventType)[keyof typeof EventType];
115
115
  declare const ItemListId: {
116
- readonly SEARCH_RESULTS: "search-results";
117
- readonly PRODUCT_LIST: "product-list";
118
- readonly YOU_MAY_ALSO_LIKE: "you-may-also-like";
119
- readonly COMPLETE_THE_LOOK: "complete-the-look";
120
- readonly COLLABORATIVE_FILTERING: "collaborative-filtering";
121
- readonly MORE_FROM_BRAND: "more-from-brand";
122
- readonly STYLE_WITH: "style-with";
123
- readonly SHOPPING_CART: "shopping-cart";
116
+ readonly SEARCH_RESULTS: "search_results";
117
+ readonly PRODUCT_LIST: "category";
118
+ readonly YOU_MAY_ALSO_LIKE: "rec_YMAL";
119
+ readonly COMPLETE_THE_LOOK: "rec_CTL";
120
+ readonly COLLABORATIVE_FILTERING: "rec_CF";
121
+ readonly MORE_FROM_BRAND: "rec_Brand";
122
+ readonly STYLE_WITH: "STW";
123
+ readonly SHOPPING_CART: "rec_CART";
124
124
  readonly ITEM_FOR_YOU: "item-for-you";
125
125
  readonly BRAND_FOR_YOU: "brand-for-you";
126
126
  };
package/dist/index.js CHANGED
@@ -42,34 +42,41 @@ var GaEventTypeReverse = {
42
42
  remove_from_wishlist: EventType.UnfavoriteProduct
43
43
  };
44
44
  var ItemListId = {
45
- SEARCH_RESULTS: "search-results",
46
- PRODUCT_LIST: "product-list",
47
- YOU_MAY_ALSO_LIKE: "you-may-also-like",
48
- COMPLETE_THE_LOOK: "complete-the-look",
49
- COLLABORATIVE_FILTERING: "collaborative-filtering",
50
- MORE_FROM_BRAND: "more-from-brand",
51
- STYLE_WITH: "style-with",
52
- SHOPPING_CART: "shopping-cart",
45
+ SEARCH_RESULTS: "search_results",
46
+ PRODUCT_LIST: "category",
47
+ YOU_MAY_ALSO_LIKE: "rec_YMAL",
48
+ COMPLETE_THE_LOOK: "rec_CTL",
49
+ COLLABORATIVE_FILTERING: "rec_CF",
50
+ MORE_FROM_BRAND: "rec_Brand",
51
+ STYLE_WITH: "STW",
52
+ SHOPPING_CART: "rec_CART",
53
53
  ITEM_FOR_YOU: "item-for-you",
54
54
  BRAND_FOR_YOU: "brand-for-you"
55
55
  };
56
56
  var LIST_ID_ALIASES = {
57
57
  Search: ItemListId.SEARCH_RESULTS,
58
+ search_results: ItemListId.SEARCH_RESULTS,
58
59
  "search-results": ItemListId.SEARCH_RESULTS,
59
60
  PLP: ItemListId.PRODUCT_LIST,
61
+ category: ItemListId.PRODUCT_LIST,
60
62
  "product-list": ItemListId.PRODUCT_LIST,
61
63
  YMAL: ItemListId.YOU_MAY_ALSO_LIKE,
64
+ rec_YMAL: ItemListId.YOU_MAY_ALSO_LIKE,
62
65
  "you-may-also-like": ItemListId.YOU_MAY_ALSO_LIKE,
63
66
  CTL: ItemListId.COMPLETE_THE_LOOK,
67
+ rec_CTL: ItemListId.COMPLETE_THE_LOOK,
64
68
  "complete-the-look": ItemListId.COMPLETE_THE_LOOK,
65
69
  CF: ItemListId.COLLABORATIVE_FILTERING,
70
+ rec_CF: ItemListId.COLLABORATIVE_FILTERING,
66
71
  "collaborative-filtering": ItemListId.COLLABORATIVE_FILTERING,
67
72
  "frequently-bought-together": ItemListId.COLLABORATIVE_FILTERING,
68
73
  Brand: ItemListId.MORE_FROM_BRAND,
74
+ rec_Brand: ItemListId.MORE_FROM_BRAND,
69
75
  "more-from-brand": ItemListId.MORE_FROM_BRAND,
70
76
  STW: ItemListId.STYLE_WITH,
71
77
  "style-with": ItemListId.STYLE_WITH,
72
78
  CART: ItemListId.SHOPPING_CART,
79
+ rec_CART: ItemListId.SHOPPING_CART,
73
80
  "shopping-cart": ItemListId.SHOPPING_CART,
74
81
  "item-for-you": ItemListId.ITEM_FOR_YOU,
75
82
  "brand-for-you": ItemListId.BRAND_FOR_YOU
@@ -291,6 +298,7 @@ async function sendToGA(eventType, props, options) {
291
298
  engagement_time_msec: 1,
292
299
  session_engaged: "1"
293
300
  };
301
+ if (options.debug) params.debug_mode = true;
294
302
  if (currency) params.currency = currency;
295
303
  if (value !== void 0) params.value = value;
296
304
  if (transaction_id) params.transaction_id = transaction_id;
@@ -595,6 +603,14 @@ var Analytics = class {
595
603
  if (props.id && !Array.isArray(props.items)) {
596
604
  props.items = [{ item_id: props.id, ...props }];
597
605
  }
606
+ if (props.item_list_id) {
607
+ props.item_list_id = normalizeItemListId(props.item_list_id) || void 0;
608
+ }
609
+ if (Array.isArray(props.items)) {
610
+ props.items = props.items.map(
611
+ (item) => item.item_list_id ? { ...item, item_list_id: normalizeItemListId(item.item_list_id) || void 0 } : item
612
+ );
613
+ }
598
614
  const metadata = this.collectMetadata();
599
615
  Object.assign(props, metadata);
600
616
  props.data_provider = "yesplz";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/analytics.ts","../src/constants.ts","../src/storage.ts","../src/ids.ts","../src/attribution.ts","../src/ga.ts","../src/beacon.ts"],"sourcesContent":["import { Platform, AppState, type AppStateStatus } from 'react-native';\nimport {\n API_EVENTS,\n EventType,\n GaEventType,\n GaEventTypeReverse,\n VERSION,\n} from './constants';\nimport { Storage, StorageKeys } from './storage';\nimport {\n generateId,\n loadIdentity,\n numericSessionId,\n saveSession,\n saveUser,\n clearUser as clearUserStorage,\n} from './ids';\nimport { handleAttribution } from './attribution';\nimport { sendToGA } from './ga';\nimport { Beacon } from './beacon';\nimport type {\n AnalyticsConfig,\n ApiEvent,\n EventMetadata,\n TrackProperties,\n} from './types';\n\nconst DEFAULT_DEBOUNCE_MS = 1000;\nconst DEFAULT_API_BASE_URL = 'https://api.yesplz.ai';\nconst DEFAULT_GA_PROXY_BASE_URL = 'https://ypsh-admin.yesplz.ai/api/mp/collect';\n\nfunction buildUserAgent(): string {\n const os = Platform.OS;\n const version = Platform.Version;\n return `YesPlzSDK-RN/${VERSION} (${os}; ${String(version)})`;\n}\n\nexport class Analytics {\n private config: Required<\n Pick<AnalyticsConfig, 'debug' | 'debounceMs' | 'cacheUserId' | 'idPrefix'>\n > &\n Omit<AnalyticsConfig, 'debug' | 'debounceMs' | 'cacheUserId' | 'idPrefix'> & {\n appId?: string;\n gaProxyUrl?: string;\n } = {\n debug: false,\n debounceMs: DEFAULT_DEBOUNCE_MS,\n cacheUserId: true,\n idPrefix: '',\n };\n\n private cid: string | null = null;\n private sessionId: string | null = null;\n private userId: string | null = null;\n private userProperties: Record<string, unknown> = {};\n private isInitialized = false;\n private initPromise: Promise<void> | null = null;\n private beacon: Beacon | null = null;\n private pendingTracks: { eventType: string; properties: TrackProperties }[] = [];\n private appStateSubscription: { remove(): void } | null = null;\n\n init(appId: string, config: AnalyticsConfig = {}): Analytics {\n if (this.isInitialized || this.initPromise) return this;\n this.initPromise = this.initInternal(appId, config);\n void this.initPromise;\n return this;\n }\n\n ready(): Promise<void> {\n return this.initPromise ?? Promise.resolve();\n }\n\n private async initInternal(appId: string, config: AnalyticsConfig): Promise<void> {\n const normalizedAppId = String(appId).trim();\n if (!normalizedAppId) {\n throw new Error('[YesPlz Analytics] appId must be a non-empty string');\n }\n\n const apiBaseUrl = (config.apiBaseUrl || DEFAULT_API_BASE_URL).replace(/\\/$/, '');\n const apiEndpoint =\n config.apiEndpoint ||\n `${apiBaseUrl}/api/v1/retailer/${encodeURIComponent(normalizedAppId)}/interactions/`;\n const gaProxyBaseUrl = config.gaProxyBaseUrl || DEFAULT_GA_PROXY_BASE_URL;\n const gaProxySep = gaProxyBaseUrl.includes('?') ? '&' : '?';\n const gaProxyUrl = `${gaProxyBaseUrl}${gaProxySep}shop=${encodeURIComponent(normalizedAppId)}`;\n\n const mergedDefaultParams: Record<string, unknown> = {\n ...(config.defaultParams || {}),\n };\n if (config.testMarker) {\n mergedDefaultParams.test_marker = config.testMarker;\n }\n\n this.config = {\n ...this.config,\n appId: normalizedAppId,\n apiEndpoint,\n apiBaseUrl,\n apiToken: config.apiToken ?? null,\n gaProxyBaseUrl,\n gaProxyUrl,\n idPrefix: config.idPrefix || '',\n defaultParams: mergedDefaultParams,\n testMarker: config.testMarker,\n debug: config.debug ?? false,\n cacheUserId: config.cacheUserId ?? true,\n debounceMs: config.debounceMs || DEFAULT_DEBOUNCE_MS,\n };\n\n const identity = await loadIdentity();\n this.cid = identity.cid;\n this.sessionId = identity.sessionId;\n this.userId = identity.userId;\n this.userProperties = identity.userProperties;\n\n if (config.userId) {\n await this.setUserInternal(config.userId, config.userProperties || {});\n }\n\n if (apiEndpoint) {\n this.beacon = new Beacon({\n apiEndpoint,\n apiToken: this.config.apiToken,\n defaultParams: this.config.defaultParams,\n idPrefix: this.config.idPrefix,\n debounceMs: this.config.debounceMs,\n debug: this.config.debug,\n });\n await this.beacon.restorePending();\n }\n\n this.appStateSubscription = AppState.addEventListener(\n 'change',\n (state: AppStateStatus) => {\n if (state === 'background' || state === 'inactive') {\n void this.beacon?.savePending();\n }\n }\n );\n\n this.isInitialized = true;\n this.log('Initialized');\n\n const queued = this.pendingTracks.splice(0, this.pendingTracks.length);\n for (const item of queued) {\n void this.dispatchTrack(item.eventType, item.properties);\n }\n }\n\n async setUser(\n userId: string | null,\n userProperties: Record<string, unknown> = {}\n ): Promise<Analytics> {\n await this.ready();\n if (userId === null) {\n this.userId = null;\n this.userProperties = {};\n await clearUserStorage();\n this.log('User cleared');\n return this;\n }\n await this.setUserInternal(userId, userProperties);\n return this;\n }\n\n private async setUserInternal(\n userId: string,\n userProperties: Record<string, unknown>\n ): Promise<void> {\n const id = String(userId);\n if (id.length === 0) {\n // eslint-disable-next-line no-console\n console.error('[YesPlz Analytics] User ID must be a non-empty value');\n return;\n }\n this.userId = id;\n this.userProperties = JSON.parse(JSON.stringify(userProperties));\n await saveUser(this.userId, this.userProperties, this.config.cacheUserId);\n this.log(`User set: ${id}`);\n }\n\n getUser(): { userId: string; userProperties: Record<string, unknown> } | null {\n if (!this.userId) return null;\n return { userId: this.userId, userProperties: this.userProperties };\n }\n\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n getClientId(): string | null {\n return this.cid;\n }\n\n track(eventType: string, properties: TrackProperties = {}): Analytics {\n if (typeof eventType !== 'string' || eventType.length === 0) {\n // eslint-disable-next-line no-console\n console.error('[YesPlz Analytics] Event type must be a non-empty string');\n return this;\n }\n\n if (!this.isInitialized) {\n this.pendingTracks.push({\n eventType,\n properties: JSON.parse(JSON.stringify(properties)),\n });\n return this;\n }\n\n void this.dispatchTrack(eventType, properties);\n return this;\n }\n\n private async dispatchTrack(\n eventType: string,\n properties: TrackProperties\n ): Promise<void> {\n const props: TrackProperties = JSON.parse(JSON.stringify(properties));\n\n await handleAttribution(eventType, props, this.config.idPrefix);\n\n if (eventType === EventType.Purchase && !props.transaction_id) {\n props.transaction_id = generateId();\n }\n\n if (props.id && !Array.isArray(props.items)) {\n props.items = [{ item_id: props.id, ...(props as Record<string, unknown>) }];\n }\n\n const metadata = this.collectMetadata();\n Object.assign(props, metadata);\n props.data_provider = 'yesplz';\n if (this.config.testMarker) {\n props.test_marker = this.config.testMarker;\n }\n\n await this.sendGA(eventType, props);\n\n const apiEventType = GaEventTypeReverse[eventType] || eventType;\n if (API_EVENTS.includes(apiEventType)) {\n this.queueApi(apiEventType, props, metadata);\n }\n }\n\n private async sendGA(eventType: string, props: TrackProperties): Promise<void> {\n if (!this.config.gaProxyUrl) return;\n if (!this.cid || !this.sessionId) return;\n\n const gaEventName = GaEventType[eventType] ?? eventType;\n await sendToGA(eventType, props, {\n gaProxyUrl: this.config.gaProxyUrl,\n clientId: this.cid,\n sessionId: this.sessionId,\n numericSessionId: numericSessionId(this.sessionId),\n userId: this.userId,\n debug: this.config.debug,\n });\n this.log(`Track: ${gaEventName}`, props.items?.length ? { items: props.items.length } : undefined);\n }\n\n private queueApi(\n eventType: string,\n props: TrackProperties,\n metadata: EventMetadata\n ): void {\n if (!this.beacon) return;\n const items = props.items && props.items.length > 0 ? props.items : [props];\n const fallbackUrl = `app://${this.config.appId ?? 'yesplz'}/`;\n const url =\n typeof props.page_location === 'string' && props.page_location.length > 0\n ? props.page_location\n : fallbackUrl;\n const referrerUrl =\n typeof props.page_referrer === 'string' && props.page_referrer.length > 0\n ? props.page_referrer\n : null;\n\n const events: ApiEvent[] = items.map((item) => {\n const merged: Record<string, unknown> = {\n ...(props as Record<string, unknown>),\n ...(item as Record<string, unknown>),\n ...metadata,\n };\n const itemId = (item as { item_id?: string }).item_id;\n if (itemId) merged.id = itemId;\n merged.identifier_type = eventType.startsWith('yp_brand_')\n ? 'brand_name'\n : 'product_id';\n\n const event: ApiEvent = {\n event_type: eventType,\n url,\n referrer_url: referrerUrl,\n user_id: this.userId,\n session_id: this.sessionId,\n extra_data: merged,\n };\n if (Object.keys(this.userProperties).length > 0) {\n event.extra_user_data = this.userProperties;\n }\n return event;\n });\n\n this.beacon.enqueueAll(events);\n }\n\n private collectMetadata(): EventMetadata {\n const metadata: EventMetadata = {\n yp_client_time: Date.now(),\n yp_platform: Platform.OS,\n yp_platform_version: String(Platform.Version),\n yp_user_agent: buildUserAgent(),\n yp_timezone_offset: new Date().getTimezoneOffset(),\n };\n try {\n metadata.yp_timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n // ignore\n }\n if (this.cid) metadata.google_client_id = this.cid;\n return metadata;\n }\n\n async flush(): Promise<Analytics> {\n await this.ready();\n await this.beacon?.flush();\n return this;\n }\n\n async reset(): Promise<Analytics> {\n await this.ready();\n this.userId = null;\n this.userProperties = {};\n await clearUserStorage();\n await Storage.removeItem(StorageKeys.PENDING_EVENTS);\n await Storage.removeItem(StorageKeys.ATTRIBUTION);\n const newSession = generateId();\n this.sessionId = newSession;\n await saveSession(newSession);\n this.log('Reset');\n return this;\n }\n\n teardown(): void {\n this.appStateSubscription?.remove();\n this.appStateSubscription = null;\n }\n\n private log(message: string, data?: unknown): void {\n if (this.config.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] ${message}`, data ?? '');\n }\n }\n}\n\nconst globalRef = (globalThis as unknown as { __yesplz_analytics_rn__?: Analytics });\nexport const analytics: Analytics =\n globalRef.__yesplz_analytics_rn__ ||\n (globalRef.__yesplz_analytics_rn__ = new Analytics());\n","export const VERSION = '0.1.0-rn';\n\nexport const EventType = {\n ViewItemList: 'view_item_list',\n ViewItem: 'yp_product_view',\n ViewProduct: 'yp_product_view',\n SelectItem: 'yp_product_select',\n SelectProduct: 'yp_product_select',\n AddToCart: 'yp_product_cart',\n RemoveFromCart: 'yp_product_remove_from_cart',\n BeginCheckout: 'yp_begin_checkout',\n Purchase: 'yp_product_purchase',\n FavoriteProduct: 'yp_product_favorite',\n UnfavoriteProduct: 'yp_product_unfavorite',\n AddToWishlist: 'yp_product_favorite',\n RemoveFromWishlist: 'yp_product_unfavorite',\n ViewBrand: 'yp_brand_view',\n FavoriteBrand: 'yp_brand_favorite',\n UnfavoriteBrand: 'yp_brand_unfavorite',\n} as const;\n\nexport type EventTypeValue = (typeof EventType)[keyof typeof EventType];\n\nexport const GaEventType: Record<string, string> = {\n [EventType.ViewProduct]: 'view_item',\n [EventType.SelectItem]: 'select_item',\n [EventType.AddToCart]: 'add_to_cart',\n [EventType.RemoveFromCart]: 'remove_from_cart',\n [EventType.BeginCheckout]: 'begin_checkout',\n [EventType.Purchase]: 'purchase',\n [EventType.FavoriteProduct]: 'add_to_wishlist',\n [EventType.UnfavoriteProduct]: 'remove_from_wishlist',\n};\n\nexport const GaEventTypeReverse: Record<string, string> = {\n view_item: EventType.ViewProduct,\n select_item: EventType.SelectItem,\n add_to_cart: EventType.AddToCart,\n remove_from_cart: EventType.RemoveFromCart,\n begin_checkout: EventType.BeginCheckout,\n purchase: EventType.Purchase,\n add_to_wishlist: EventType.FavoriteProduct,\n remove_from_wishlist: EventType.UnfavoriteProduct,\n};\n\nexport const ItemListId = {\n SEARCH_RESULTS: 'search-results',\n PRODUCT_LIST: 'product-list',\n YOU_MAY_ALSO_LIKE: 'you-may-also-like',\n COMPLETE_THE_LOOK: 'complete-the-look',\n COLLABORATIVE_FILTERING: 'collaborative-filtering',\n MORE_FROM_BRAND: 'more-from-brand',\n STYLE_WITH: 'style-with',\n SHOPPING_CART: 'shopping-cart',\n ITEM_FOR_YOU: 'item-for-you',\n BRAND_FOR_YOU: 'brand-for-you',\n} as const;\n\nexport type ItemListIdValue = (typeof ItemListId)[keyof typeof ItemListId];\n\nconst LIST_ID_ALIASES: Record<string, string> = {\n Search: ItemListId.SEARCH_RESULTS,\n 'search-results': ItemListId.SEARCH_RESULTS,\n PLP: ItemListId.PRODUCT_LIST,\n 'product-list': ItemListId.PRODUCT_LIST,\n YMAL: ItemListId.YOU_MAY_ALSO_LIKE,\n 'you-may-also-like': ItemListId.YOU_MAY_ALSO_LIKE,\n CTL: ItemListId.COMPLETE_THE_LOOK,\n 'complete-the-look': ItemListId.COMPLETE_THE_LOOK,\n CF: ItemListId.COLLABORATIVE_FILTERING,\n 'collaborative-filtering': ItemListId.COLLABORATIVE_FILTERING,\n 'frequently-bought-together': ItemListId.COLLABORATIVE_FILTERING,\n Brand: ItemListId.MORE_FROM_BRAND,\n 'more-from-brand': ItemListId.MORE_FROM_BRAND,\n STW: ItemListId.STYLE_WITH,\n 'style-with': ItemListId.STYLE_WITH,\n CART: ItemListId.SHOPPING_CART,\n 'shopping-cart': ItemListId.SHOPPING_CART,\n 'item-for-you': ItemListId.ITEM_FOR_YOU,\n 'brand-for-you': ItemListId.BRAND_FOR_YOU,\n};\n\nexport function normalizeItemListId(input: string | undefined | null): string | undefined | null {\n if (!input) return input;\n const alias = LIST_ID_ALIASES[input];\n if (alias) return alias;\n const canonical = Object.values(ItemListId) as string[];\n if (canonical.includes(input)) return input;\n return input;\n}\n\nexport const API_EVENTS: string[] = [\n EventType.ViewProduct,\n EventType.AddToCart,\n EventType.RemoveFromCart,\n EventType.BeginCheckout,\n EventType.Purchase,\n EventType.FavoriteProduct,\n EventType.UnfavoriteProduct,\n EventType.ViewBrand,\n EventType.FavoriteBrand,\n EventType.UnfavoriteBrand,\n];\n","import AsyncStorage from '@react-native-async-storage/async-storage';\n\nexport const StorageKeys = {\n CID: 'yp_cid',\n SESSION: 'yp_session',\n USER_ID: 'yp_user_id',\n USER_PROPS: 'yp_user_props',\n ATTRIBUTION: 'yp_attribution',\n PENDING_EVENTS: 'yp_pending_events',\n} as const;\n\nexport const Storage = {\n async getItem(key: string): Promise<string | null> {\n try {\n return await AsyncStorage.getItem(key);\n } catch {\n return null;\n }\n },\n async setItem(key: string, value: string): Promise<void> {\n try {\n await AsyncStorage.setItem(key, value);\n } catch {\n // ignore\n }\n },\n async removeItem(key: string): Promise<void> {\n try {\n await AsyncStorage.removeItem(key);\n } catch {\n // ignore\n }\n },\n async getJSON<T>(key: string, fallback: T): Promise<T> {\n const raw = await Storage.getItem(key);\n if (!raw) return fallback;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return fallback;\n }\n },\n async setJSON(key: string, value: unknown): Promise<void> {\n try {\n await Storage.setItem(key, JSON.stringify(value));\n } catch {\n // ignore\n }\n },\n};\n","import { Storage, StorageKeys } from './storage';\n\nexport function generateId(): string {\n return Date.now().toString(36) + Math.random().toString(36).substring(2);\n}\n\nexport function hashCode(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n hash = (hash << 5) - hash + str.charCodeAt(i);\n hash |= 0;\n }\n return hash;\n}\n\nexport function numericSessionId(sessionId: string | null | undefined): number {\n if (!sessionId) return Math.floor(Date.now() / 1000);\n return Math.abs(hashCode(sessionId)) || Math.floor(Date.now() / 1000);\n}\n\nexport interface Identity {\n cid: string;\n sessionId: string;\n userId: string | null;\n userProperties: Record<string, unknown>;\n}\n\nexport async function loadIdentity(): Promise<Identity> {\n const [cidStored, sessionStored, userIdStored, userPropsStored] = await Promise.all([\n Storage.getItem(StorageKeys.CID),\n Storage.getItem(StorageKeys.SESSION),\n Storage.getItem(StorageKeys.USER_ID),\n Storage.getItem(StorageKeys.USER_PROPS),\n ]);\n\n let cid = cidStored;\n if (!cid) {\n cid = generateId();\n await Storage.setItem(StorageKeys.CID, cid);\n }\n\n let sessionId = sessionStored;\n if (!sessionId) {\n sessionId = generateId();\n await Storage.setItem(StorageKeys.SESSION, sessionId);\n }\n\n let userProperties: Record<string, unknown> = {};\n if (userPropsStored) {\n try {\n userProperties = JSON.parse(userPropsStored) as Record<string, unknown>;\n } catch {\n userProperties = {};\n }\n }\n\n return { cid, sessionId, userId: userIdStored, userProperties };\n}\n\nexport async function saveCid(cid: string): Promise<void> {\n await Storage.setItem(StorageKeys.CID, cid);\n}\n\nexport async function saveSession(sessionId: string): Promise<void> {\n await Storage.setItem(StorageKeys.SESSION, sessionId);\n}\n\nexport async function saveUser(\n userId: string,\n userProperties: Record<string, unknown>,\n cacheUserId: boolean\n): Promise<void> {\n if (cacheUserId) {\n await Storage.setItem(StorageKeys.USER_ID, userId);\n }\n await Storage.setJSON(StorageKeys.USER_PROPS, userProperties);\n}\n\nexport async function clearUser(): Promise<void> {\n await Storage.removeItem(StorageKeys.USER_ID);\n await Storage.removeItem(StorageKeys.USER_PROPS);\n}\n","import { Storage, StorageKeys } from './storage';\nimport { EventType, GaEventTypeReverse } from './constants';\nimport type { TrackProperties } from './types';\n\nconst EXPIRY_MS = 30 * 60 * 1000;\n\ntype AttributionRecord = { source: string; ts: number };\ntype AttributionStore = Record<string, AttributionRecord>;\n\nfunction normalizeId(rawId: unknown, idPrefix?: string): string | null {\n if (!rawId) return null;\n const idStr = String(rawId);\n if (idPrefix && idStr.startsWith(idPrefix)) {\n return idStr.slice(idPrefix.length);\n }\n const match = idStr.match(/^[a-zA-Z]+-(.+)$/);\n return match ? match[1] : idStr;\n}\n\nasync function loadStore(): Promise<AttributionStore> {\n return Storage.getJSON<AttributionStore>(StorageKeys.ATTRIBUTION, {});\n}\n\nasync function saveStore(store: AttributionStore): Promise<void> {\n await Storage.setJSON(StorageKeys.ATTRIBUTION, store);\n}\n\nfunction pruneExpired(store: AttributionStore): AttributionStore {\n const now = Date.now();\n const next: AttributionStore = {};\n for (const [k, v] of Object.entries(store)) {\n if (now - v.ts <= EXPIRY_MS) next[k] = v;\n }\n return next;\n}\n\nexport async function handleAttribution(\n eventType: string,\n props: TrackProperties,\n idPrefix?: string\n): Promise<void> {\n const normalizedEventType = GaEventTypeReverse[eventType] || eventType;\n\n if (normalizedEventType === EventType.SelectItem) {\n const itemListId = props.item_list_id;\n const rawId = props.id ?? props.items?.[0]?.item_id;\n const productId = normalizeId(rawId, idPrefix);\n if (itemListId && productId) {\n let store = await loadStore();\n store = pruneExpired(store);\n store[productId] = { source: itemListId, ts: Date.now() };\n await saveStore(store);\n }\n return;\n }\n\n if (normalizedEventType === EventType.ViewProduct) {\n const rawId = props.id ?? props.items?.[0]?.item_id;\n const productId = normalizeId(rawId, idPrefix);\n if (!productId) return;\n const store = await loadStore();\n const entry = store[productId];\n if (entry && Date.now() - entry.ts <= EXPIRY_MS) {\n props.item_list_id = entry.source;\n if (Array.isArray(props.items)) {\n props.items = props.items.map((item) => ({ ...item, item_list_id: entry.source }));\n }\n }\n return;\n }\n\n if (normalizedEventType === EventType.AddToCart) {\n if (!Array.isArray(props.items)) return;\n const store = await loadStore();\n props.items = props.items.map((item) => {\n const productId = normalizeId(item.item_id, idPrefix);\n const entry = productId ? store[productId] : null;\n if (entry && Date.now() - entry.ts <= EXPIRY_MS) {\n return { ...item, item_list_id: entry.source };\n }\n return item;\n });\n const firstMatch = props.items.find((item) => item.item_list_id);\n if (firstMatch?.item_list_id) {\n props.item_list_id = firstMatch.item_list_id;\n }\n }\n}\n\nexport async function getAttribution(productId: string): Promise<string | null> {\n const store = await loadStore();\n const entry = store[String(productId)];\n if (entry && Date.now() - entry.ts < EXPIRY_MS) return entry.source;\n return null;\n}\n","import { GaEventType } from './constants';\nimport type { TrackProperties } from './types';\n\nfunction toSnakeCase(str: string): string {\n return str.replace(/-/g, '_');\n}\n\nexport interface GaSendOptions {\n gaProxyUrl: string;\n clientId: string;\n sessionId: string;\n numericSessionId: number;\n userId?: string | null;\n debug?: boolean;\n}\n\nexport async function sendToGA(\n eventType: string,\n props: TrackProperties,\n options: GaSendOptions\n): Promise<void> {\n const gaEvent = GaEventType[eventType] || toSnakeCase(eventType);\n const {\n items,\n currency,\n value,\n transaction_id,\n tax,\n shipping,\n coupon,\n ...rest\n } = props;\n\n const params: Record<string, unknown> = {\n session_id: options.numericSessionId,\n engagement_time_msec: 1,\n session_engaged: '1',\n };\n\n if (currency) params.currency = currency;\n if (value !== undefined) params.value = value;\n if (transaction_id) params.transaction_id = transaction_id;\n if (tax !== undefined) params.tax = tax;\n if (shipping !== undefined) params.shipping = shipping;\n if (coupon) params.coupon = coupon;\n if (items) params.items = items;\n\n const passthroughKeys = [\n 'item_list_id',\n 'data_provider',\n 'event_source',\n 'id',\n 'search_term',\n 'total',\n 'total_text',\n 'total_vector',\n 'page_location',\n 'page_title',\n 'page_referrer',\n 'language',\n 'test_marker',\n 'yp_platform',\n 'yp_platform_version',\n 'yp_user_agent',\n ];\n for (const key of passthroughKeys) {\n if (rest[key] !== undefined) params[key] = rest[key];\n }\n\n const body: Record<string, unknown> = {\n client_id: options.clientId || options.sessionId,\n timestamp_micros: Date.now() * 1000,\n events: [{ name: gaEvent, params }],\n };\n\n if (options.userId) body.user_id = options.userId;\n\n const sep = options.gaProxyUrl.includes('?') ? '&' : '?';\n const url = options.debug\n ? `${options.gaProxyUrl}${sep}debug=1`\n : options.gaProxyUrl;\n\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n if (options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] GA MP → ${gaEvent} (status ${res.status})`);\n }\n } catch (e) {\n if (options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] GA MP error: ${(e as Error).message}`);\n }\n }\n}\n","import { Storage, StorageKeys } from './storage';\nimport type { ApiEvent } from './types';\n\nexport interface BeaconOptions {\n apiEndpoint: string;\n apiToken?: string | null;\n defaultParams?: Record<string, unknown>;\n idPrefix?: string;\n debounceMs?: number;\n debug?: boolean;\n}\n\nexport class Beacon {\n private queue: ApiEvent[] = [];\n private isSending = false;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(private options: BeaconOptions) {}\n\n enqueue(event: ApiEvent): void {\n this.queue.push(event);\n this.scheduleSend();\n }\n\n enqueueAll(events: ApiEvent[]): void {\n this.queue.push(...events);\n this.scheduleSend();\n }\n\n private scheduleSend(): void {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(() => {\n void this.send();\n }, this.options.debounceMs ?? 1000);\n }\n\n async send(retryCount = 0): Promise<void> {\n if (this.queue.length === 0) return;\n if (!this.options.apiEndpoint) return;\n if (this.isSending) return;\n\n this.isSending = true;\n const eventsToSend = this.queue.splice(0, this.queue.length);\n\n const events = eventsToSend.map((event) => {\n const merged: Record<string, unknown> = {\n ...event,\n ...(this.options.defaultParams ?? {}),\n };\n const rawId = (event.extra_data as Record<string, unknown>).id;\n if (rawId && this.options.idPrefix) {\n merged.extra_data = {\n ...event.extra_data,\n id: `${this.options.idPrefix}${rawId}`,\n };\n }\n return merged;\n });\n\n try {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.options.apiToken) headers.Authorization = `Token ${this.options.apiToken}`;\n\n const res = await fetch(this.options.apiEndpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify(events),\n });\n\n if (res.status > 299) {\n throw new Error(`Failed to send events (status ${res.status})`);\n }\n\n if (this.options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] Sync: ${events.length} events sent`);\n }\n await Storage.removeItem(StorageKeys.PENDING_EVENTS);\n } catch (e) {\n if (this.options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] Sync failed: ${(e as Error).message}`);\n }\n this.queue.unshift(...eventsToSend);\n this.isSending = false;\n if (retryCount < 1) {\n setTimeout(() => void this.send(retryCount + 1), 2000);\n }\n return;\n }\n\n this.isSending = false;\n if (this.queue.length > 0) this.scheduleSend();\n }\n\n async flush(): Promise<void> {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n await this.send();\n }\n\n async savePending(): Promise<void> {\n if (this.queue.length === 0) return;\n const toSave = this.queue.slice(-100);\n await Storage.setJSON(StorageKeys.PENDING_EVENTS, toSave);\n this.queue = [];\n }\n\n async restorePending(): Promise<void> {\n const pending = await Storage.getJSON<ApiEvent[]>(StorageKeys.PENDING_EVENTS, []);\n if (pending.length > 0) {\n this.queue.unshift(...pending);\n await Storage.removeItem(StorageKeys.PENDING_EVENTS);\n this.scheduleSend();\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/analytics.ts","../src/constants.ts","../src/storage.ts","../src/ids.ts","../src/attribution.ts","../src/ga.ts","../src/beacon.ts"],"sourcesContent":["import { Platform, AppState, type AppStateStatus } from 'react-native';\nimport {\n API_EVENTS,\n EventType,\n GaEventType,\n GaEventTypeReverse,\n normalizeItemListId,\n VERSION,\n} from './constants';\nimport { Storage, StorageKeys } from './storage';\nimport {\n generateId,\n loadIdentity,\n numericSessionId,\n saveSession,\n saveUser,\n clearUser as clearUserStorage,\n} from './ids';\nimport { handleAttribution } from './attribution';\nimport { sendToGA } from './ga';\nimport { Beacon } from './beacon';\nimport type {\n AnalyticsConfig,\n ApiEvent,\n EventMetadata,\n TrackProperties,\n} from './types';\n\nconst DEFAULT_DEBOUNCE_MS = 1000;\nconst DEFAULT_API_BASE_URL = 'https://api.yesplz.ai';\nconst DEFAULT_GA_PROXY_BASE_URL = 'https://ypsh-admin.yesplz.ai/api/mp/collect';\n\nfunction buildUserAgent(): string {\n const os = Platform.OS;\n const version = Platform.Version;\n return `YesPlzSDK-RN/${VERSION} (${os}; ${String(version)})`;\n}\n\nexport class Analytics {\n private config: Required<\n Pick<AnalyticsConfig, 'debug' | 'debounceMs' | 'cacheUserId' | 'idPrefix'>\n > &\n Omit<AnalyticsConfig, 'debug' | 'debounceMs' | 'cacheUserId' | 'idPrefix'> & {\n appId?: string;\n gaProxyUrl?: string;\n } = {\n debug: false,\n debounceMs: DEFAULT_DEBOUNCE_MS,\n cacheUserId: true,\n idPrefix: '',\n };\n\n private cid: string | null = null;\n private sessionId: string | null = null;\n private userId: string | null = null;\n private userProperties: Record<string, unknown> = {};\n private isInitialized = false;\n private initPromise: Promise<void> | null = null;\n private beacon: Beacon | null = null;\n private pendingTracks: { eventType: string; properties: TrackProperties }[] = [];\n private appStateSubscription: { remove(): void } | null = null;\n\n init(appId: string, config: AnalyticsConfig = {}): Analytics {\n if (this.isInitialized || this.initPromise) return this;\n this.initPromise = this.initInternal(appId, config);\n void this.initPromise;\n return this;\n }\n\n ready(): Promise<void> {\n return this.initPromise ?? Promise.resolve();\n }\n\n private async initInternal(appId: string, config: AnalyticsConfig): Promise<void> {\n const normalizedAppId = String(appId).trim();\n if (!normalizedAppId) {\n throw new Error('[YesPlz Analytics] appId must be a non-empty string');\n }\n\n const apiBaseUrl = (config.apiBaseUrl || DEFAULT_API_BASE_URL).replace(/\\/$/, '');\n const apiEndpoint =\n config.apiEndpoint ||\n `${apiBaseUrl}/api/v1/retailer/${encodeURIComponent(normalizedAppId)}/interactions/`;\n const gaProxyBaseUrl = config.gaProxyBaseUrl || DEFAULT_GA_PROXY_BASE_URL;\n const gaProxySep = gaProxyBaseUrl.includes('?') ? '&' : '?';\n const gaProxyUrl = `${gaProxyBaseUrl}${gaProxySep}shop=${encodeURIComponent(normalizedAppId)}`;\n\n const mergedDefaultParams: Record<string, unknown> = {\n ...(config.defaultParams || {}),\n };\n if (config.testMarker) {\n mergedDefaultParams.test_marker = config.testMarker;\n }\n\n this.config = {\n ...this.config,\n appId: normalizedAppId,\n apiEndpoint,\n apiBaseUrl,\n apiToken: config.apiToken ?? null,\n gaProxyBaseUrl,\n gaProxyUrl,\n idPrefix: config.idPrefix || '',\n defaultParams: mergedDefaultParams,\n testMarker: config.testMarker,\n debug: config.debug ?? false,\n cacheUserId: config.cacheUserId ?? true,\n debounceMs: config.debounceMs || DEFAULT_DEBOUNCE_MS,\n };\n\n const identity = await loadIdentity();\n this.cid = identity.cid;\n this.sessionId = identity.sessionId;\n this.userId = identity.userId;\n this.userProperties = identity.userProperties;\n\n if (config.userId) {\n await this.setUserInternal(config.userId, config.userProperties || {});\n }\n\n if (apiEndpoint) {\n this.beacon = new Beacon({\n apiEndpoint,\n apiToken: this.config.apiToken,\n defaultParams: this.config.defaultParams,\n idPrefix: this.config.idPrefix,\n debounceMs: this.config.debounceMs,\n debug: this.config.debug,\n });\n await this.beacon.restorePending();\n }\n\n this.appStateSubscription = AppState.addEventListener(\n 'change',\n (state: AppStateStatus) => {\n if (state === 'background' || state === 'inactive') {\n void this.beacon?.savePending();\n }\n }\n );\n\n this.isInitialized = true;\n this.log('Initialized');\n\n const queued = this.pendingTracks.splice(0, this.pendingTracks.length);\n for (const item of queued) {\n void this.dispatchTrack(item.eventType, item.properties);\n }\n }\n\n async setUser(\n userId: string | null,\n userProperties: Record<string, unknown> = {}\n ): Promise<Analytics> {\n await this.ready();\n if (userId === null) {\n this.userId = null;\n this.userProperties = {};\n await clearUserStorage();\n this.log('User cleared');\n return this;\n }\n await this.setUserInternal(userId, userProperties);\n return this;\n }\n\n private async setUserInternal(\n userId: string,\n userProperties: Record<string, unknown>\n ): Promise<void> {\n const id = String(userId);\n if (id.length === 0) {\n // eslint-disable-next-line no-console\n console.error('[YesPlz Analytics] User ID must be a non-empty value');\n return;\n }\n this.userId = id;\n this.userProperties = JSON.parse(JSON.stringify(userProperties));\n await saveUser(this.userId, this.userProperties, this.config.cacheUserId);\n this.log(`User set: ${id}`);\n }\n\n getUser(): { userId: string; userProperties: Record<string, unknown> } | null {\n if (!this.userId) return null;\n return { userId: this.userId, userProperties: this.userProperties };\n }\n\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n getClientId(): string | null {\n return this.cid;\n }\n\n track(eventType: string, properties: TrackProperties = {}): Analytics {\n if (typeof eventType !== 'string' || eventType.length === 0) {\n // eslint-disable-next-line no-console\n console.error('[YesPlz Analytics] Event type must be a non-empty string');\n return this;\n }\n\n if (!this.isInitialized) {\n this.pendingTracks.push({\n eventType,\n properties: JSON.parse(JSON.stringify(properties)),\n });\n return this;\n }\n\n void this.dispatchTrack(eventType, properties);\n return this;\n }\n\n private async dispatchTrack(\n eventType: string,\n properties: TrackProperties\n ): Promise<void> {\n const props: TrackProperties = JSON.parse(JSON.stringify(properties));\n\n await handleAttribution(eventType, props, this.config.idPrefix);\n\n if (eventType === EventType.Purchase && !props.transaction_id) {\n props.transaction_id = generateId();\n }\n\n if (props.id && !Array.isArray(props.items)) {\n props.items = [{ item_id: props.id, ...(props as Record<string, unknown>) }];\n }\n\n if (props.item_list_id) {\n props.item_list_id = normalizeItemListId(props.item_list_id) || undefined;\n }\n if (Array.isArray(props.items)) {\n props.items = props.items.map((item) =>\n item.item_list_id ? { ...item, item_list_id: normalizeItemListId(item.item_list_id) || undefined } : item\n );\n }\n\n const metadata = this.collectMetadata();\n Object.assign(props, metadata);\n props.data_provider = 'yesplz';\n if (this.config.testMarker) {\n props.test_marker = this.config.testMarker;\n }\n\n await this.sendGA(eventType, props);\n\n const apiEventType = GaEventTypeReverse[eventType] || eventType;\n if (API_EVENTS.includes(apiEventType)) {\n this.queueApi(apiEventType, props, metadata);\n }\n }\n\n private async sendGA(eventType: string, props: TrackProperties): Promise<void> {\n if (!this.config.gaProxyUrl) return;\n if (!this.cid || !this.sessionId) return;\n\n const gaEventName = GaEventType[eventType] ?? eventType;\n await sendToGA(eventType, props, {\n gaProxyUrl: this.config.gaProxyUrl,\n clientId: this.cid,\n sessionId: this.sessionId,\n numericSessionId: numericSessionId(this.sessionId),\n userId: this.userId,\n debug: this.config.debug,\n });\n this.log(`Track: ${gaEventName}`, props.items?.length ? { items: props.items.length } : undefined);\n }\n\n private queueApi(\n eventType: string,\n props: TrackProperties,\n metadata: EventMetadata\n ): void {\n if (!this.beacon) return;\n const items = props.items && props.items.length > 0 ? props.items : [props];\n const fallbackUrl = `app://${this.config.appId ?? 'yesplz'}/`;\n const url =\n typeof props.page_location === 'string' && props.page_location.length > 0\n ? props.page_location\n : fallbackUrl;\n const referrerUrl =\n typeof props.page_referrer === 'string' && props.page_referrer.length > 0\n ? props.page_referrer\n : null;\n\n const events: ApiEvent[] = items.map((item) => {\n const merged: Record<string, unknown> = {\n ...(props as Record<string, unknown>),\n ...(item as Record<string, unknown>),\n ...metadata,\n };\n const itemId = (item as { item_id?: string }).item_id;\n if (itemId) merged.id = itemId;\n merged.identifier_type = eventType.startsWith('yp_brand_')\n ? 'brand_name'\n : 'product_id';\n\n const event: ApiEvent = {\n event_type: eventType,\n url,\n referrer_url: referrerUrl,\n user_id: this.userId,\n session_id: this.sessionId,\n extra_data: merged,\n };\n if (Object.keys(this.userProperties).length > 0) {\n event.extra_user_data = this.userProperties;\n }\n return event;\n });\n\n this.beacon.enqueueAll(events);\n }\n\n private collectMetadata(): EventMetadata {\n const metadata: EventMetadata = {\n yp_client_time: Date.now(),\n yp_platform: Platform.OS,\n yp_platform_version: String(Platform.Version),\n yp_user_agent: buildUserAgent(),\n yp_timezone_offset: new Date().getTimezoneOffset(),\n };\n try {\n metadata.yp_timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch {\n // ignore\n }\n if (this.cid) metadata.google_client_id = this.cid;\n return metadata;\n }\n\n async flush(): Promise<Analytics> {\n await this.ready();\n await this.beacon?.flush();\n return this;\n }\n\n async reset(): Promise<Analytics> {\n await this.ready();\n this.userId = null;\n this.userProperties = {};\n await clearUserStorage();\n await Storage.removeItem(StorageKeys.PENDING_EVENTS);\n await Storage.removeItem(StorageKeys.ATTRIBUTION);\n const newSession = generateId();\n this.sessionId = newSession;\n await saveSession(newSession);\n this.log('Reset');\n return this;\n }\n\n teardown(): void {\n this.appStateSubscription?.remove();\n this.appStateSubscription = null;\n }\n\n private log(message: string, data?: unknown): void {\n if (this.config.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] ${message}`, data ?? '');\n }\n }\n}\n\nconst globalRef = (globalThis as unknown as { __yesplz_analytics_rn__?: Analytics });\nexport const analytics: Analytics =\n globalRef.__yesplz_analytics_rn__ ||\n (globalRef.__yesplz_analytics_rn__ = new Analytics());\n","export const VERSION = '0.1.0-rn';\n\nexport const EventType = {\n ViewItemList: 'view_item_list',\n ViewItem: 'yp_product_view',\n ViewProduct: 'yp_product_view',\n SelectItem: 'yp_product_select',\n SelectProduct: 'yp_product_select',\n AddToCart: 'yp_product_cart',\n RemoveFromCart: 'yp_product_remove_from_cart',\n BeginCheckout: 'yp_begin_checkout',\n Purchase: 'yp_product_purchase',\n FavoriteProduct: 'yp_product_favorite',\n UnfavoriteProduct: 'yp_product_unfavorite',\n AddToWishlist: 'yp_product_favorite',\n RemoveFromWishlist: 'yp_product_unfavorite',\n ViewBrand: 'yp_brand_view',\n FavoriteBrand: 'yp_brand_favorite',\n UnfavoriteBrand: 'yp_brand_unfavorite',\n} as const;\n\nexport type EventTypeValue = (typeof EventType)[keyof typeof EventType];\n\nexport const GaEventType: Record<string, string> = {\n [EventType.ViewProduct]: 'view_item',\n [EventType.SelectItem]: 'select_item',\n [EventType.AddToCart]: 'add_to_cart',\n [EventType.RemoveFromCart]: 'remove_from_cart',\n [EventType.BeginCheckout]: 'begin_checkout',\n [EventType.Purchase]: 'purchase',\n [EventType.FavoriteProduct]: 'add_to_wishlist',\n [EventType.UnfavoriteProduct]: 'remove_from_wishlist',\n};\n\nexport const GaEventTypeReverse: Record<string, string> = {\n view_item: EventType.ViewProduct,\n select_item: EventType.SelectItem,\n add_to_cart: EventType.AddToCart,\n remove_from_cart: EventType.RemoveFromCart,\n begin_checkout: EventType.BeginCheckout,\n purchase: EventType.Purchase,\n add_to_wishlist: EventType.FavoriteProduct,\n remove_from_wishlist: EventType.UnfavoriteProduct,\n};\n\nexport const ItemListId = {\n SEARCH_RESULTS: 'search_results',\n PRODUCT_LIST: 'category',\n YOU_MAY_ALSO_LIKE: 'rec_YMAL',\n COMPLETE_THE_LOOK: 'rec_CTL',\n COLLABORATIVE_FILTERING: 'rec_CF',\n MORE_FROM_BRAND: 'rec_Brand',\n STYLE_WITH: 'STW',\n SHOPPING_CART: 'rec_CART',\n ITEM_FOR_YOU: 'item-for-you',\n BRAND_FOR_YOU: 'brand-for-you',\n} as const;\n\nexport type ItemListIdValue = (typeof ItemListId)[keyof typeof ItemListId];\n\nconst LIST_ID_ALIASES: Record<string, string> = {\n Search: ItemListId.SEARCH_RESULTS,\n search_results: ItemListId.SEARCH_RESULTS,\n 'search-results': ItemListId.SEARCH_RESULTS,\n PLP: ItemListId.PRODUCT_LIST,\n category: ItemListId.PRODUCT_LIST,\n 'product-list': ItemListId.PRODUCT_LIST,\n YMAL: ItemListId.YOU_MAY_ALSO_LIKE,\n rec_YMAL: ItemListId.YOU_MAY_ALSO_LIKE,\n 'you-may-also-like': ItemListId.YOU_MAY_ALSO_LIKE,\n CTL: ItemListId.COMPLETE_THE_LOOK,\n rec_CTL: ItemListId.COMPLETE_THE_LOOK,\n 'complete-the-look': ItemListId.COMPLETE_THE_LOOK,\n CF: ItemListId.COLLABORATIVE_FILTERING,\n rec_CF: ItemListId.COLLABORATIVE_FILTERING,\n 'collaborative-filtering': ItemListId.COLLABORATIVE_FILTERING,\n 'frequently-bought-together': ItemListId.COLLABORATIVE_FILTERING,\n Brand: ItemListId.MORE_FROM_BRAND,\n rec_Brand: ItemListId.MORE_FROM_BRAND,\n 'more-from-brand': ItemListId.MORE_FROM_BRAND,\n STW: ItemListId.STYLE_WITH,\n 'style-with': ItemListId.STYLE_WITH,\n CART: ItemListId.SHOPPING_CART,\n rec_CART: ItemListId.SHOPPING_CART,\n 'shopping-cart': ItemListId.SHOPPING_CART,\n 'item-for-you': ItemListId.ITEM_FOR_YOU,\n 'brand-for-you': ItemListId.BRAND_FOR_YOU,\n};\n\nexport function normalizeItemListId(input: string | undefined | null): string | undefined | null {\n if (!input) return input;\n const alias = LIST_ID_ALIASES[input];\n if (alias) return alias;\n const canonical = Object.values(ItemListId) as string[];\n if (canonical.includes(input)) return input;\n return input;\n}\n\nexport const API_EVENTS: string[] = [\n EventType.ViewProduct,\n EventType.AddToCart,\n EventType.RemoveFromCart,\n EventType.BeginCheckout,\n EventType.Purchase,\n EventType.FavoriteProduct,\n EventType.UnfavoriteProduct,\n EventType.ViewBrand,\n EventType.FavoriteBrand,\n EventType.UnfavoriteBrand,\n];\n","import AsyncStorage from '@react-native-async-storage/async-storage';\n\nexport const StorageKeys = {\n CID: 'yp_cid',\n SESSION: 'yp_session',\n USER_ID: 'yp_user_id',\n USER_PROPS: 'yp_user_props',\n ATTRIBUTION: 'yp_attribution',\n PENDING_EVENTS: 'yp_pending_events',\n} as const;\n\nexport const Storage = {\n async getItem(key: string): Promise<string | null> {\n try {\n return await AsyncStorage.getItem(key);\n } catch {\n return null;\n }\n },\n async setItem(key: string, value: string): Promise<void> {\n try {\n await AsyncStorage.setItem(key, value);\n } catch {\n // ignore\n }\n },\n async removeItem(key: string): Promise<void> {\n try {\n await AsyncStorage.removeItem(key);\n } catch {\n // ignore\n }\n },\n async getJSON<T>(key: string, fallback: T): Promise<T> {\n const raw = await Storage.getItem(key);\n if (!raw) return fallback;\n try {\n return JSON.parse(raw) as T;\n } catch {\n return fallback;\n }\n },\n async setJSON(key: string, value: unknown): Promise<void> {\n try {\n await Storage.setItem(key, JSON.stringify(value));\n } catch {\n // ignore\n }\n },\n};\n","import { Storage, StorageKeys } from './storage';\n\nexport function generateId(): string {\n return Date.now().toString(36) + Math.random().toString(36).substring(2);\n}\n\nexport function hashCode(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n hash = (hash << 5) - hash + str.charCodeAt(i);\n hash |= 0;\n }\n return hash;\n}\n\nexport function numericSessionId(sessionId: string | null | undefined): number {\n if (!sessionId) return Math.floor(Date.now() / 1000);\n return Math.abs(hashCode(sessionId)) || Math.floor(Date.now() / 1000);\n}\n\nexport interface Identity {\n cid: string;\n sessionId: string;\n userId: string | null;\n userProperties: Record<string, unknown>;\n}\n\nexport async function loadIdentity(): Promise<Identity> {\n const [cidStored, sessionStored, userIdStored, userPropsStored] = await Promise.all([\n Storage.getItem(StorageKeys.CID),\n Storage.getItem(StorageKeys.SESSION),\n Storage.getItem(StorageKeys.USER_ID),\n Storage.getItem(StorageKeys.USER_PROPS),\n ]);\n\n let cid = cidStored;\n if (!cid) {\n cid = generateId();\n await Storage.setItem(StorageKeys.CID, cid);\n }\n\n let sessionId = sessionStored;\n if (!sessionId) {\n sessionId = generateId();\n await Storage.setItem(StorageKeys.SESSION, sessionId);\n }\n\n let userProperties: Record<string, unknown> = {};\n if (userPropsStored) {\n try {\n userProperties = JSON.parse(userPropsStored) as Record<string, unknown>;\n } catch {\n userProperties = {};\n }\n }\n\n return { cid, sessionId, userId: userIdStored, userProperties };\n}\n\nexport async function saveCid(cid: string): Promise<void> {\n await Storage.setItem(StorageKeys.CID, cid);\n}\n\nexport async function saveSession(sessionId: string): Promise<void> {\n await Storage.setItem(StorageKeys.SESSION, sessionId);\n}\n\nexport async function saveUser(\n userId: string,\n userProperties: Record<string, unknown>,\n cacheUserId: boolean\n): Promise<void> {\n if (cacheUserId) {\n await Storage.setItem(StorageKeys.USER_ID, userId);\n }\n await Storage.setJSON(StorageKeys.USER_PROPS, userProperties);\n}\n\nexport async function clearUser(): Promise<void> {\n await Storage.removeItem(StorageKeys.USER_ID);\n await Storage.removeItem(StorageKeys.USER_PROPS);\n}\n","import { Storage, StorageKeys } from './storage';\nimport { EventType, GaEventTypeReverse } from './constants';\nimport type { TrackProperties } from './types';\n\nconst EXPIRY_MS = 30 * 60 * 1000;\n\ntype AttributionRecord = { source: string; ts: number };\ntype AttributionStore = Record<string, AttributionRecord>;\n\nfunction normalizeId(rawId: unknown, idPrefix?: string): string | null {\n if (!rawId) return null;\n const idStr = String(rawId);\n if (idPrefix && idStr.startsWith(idPrefix)) {\n return idStr.slice(idPrefix.length);\n }\n const match = idStr.match(/^[a-zA-Z]+-(.+)$/);\n return match ? match[1] : idStr;\n}\n\nasync function loadStore(): Promise<AttributionStore> {\n return Storage.getJSON<AttributionStore>(StorageKeys.ATTRIBUTION, {});\n}\n\nasync function saveStore(store: AttributionStore): Promise<void> {\n await Storage.setJSON(StorageKeys.ATTRIBUTION, store);\n}\n\nfunction pruneExpired(store: AttributionStore): AttributionStore {\n const now = Date.now();\n const next: AttributionStore = {};\n for (const [k, v] of Object.entries(store)) {\n if (now - v.ts <= EXPIRY_MS) next[k] = v;\n }\n return next;\n}\n\nexport async function handleAttribution(\n eventType: string,\n props: TrackProperties,\n idPrefix?: string\n): Promise<void> {\n const normalizedEventType = GaEventTypeReverse[eventType] || eventType;\n\n if (normalizedEventType === EventType.SelectItem) {\n const itemListId = props.item_list_id;\n const rawId = props.id ?? props.items?.[0]?.item_id;\n const productId = normalizeId(rawId, idPrefix);\n if (itemListId && productId) {\n let store = await loadStore();\n store = pruneExpired(store);\n store[productId] = { source: itemListId, ts: Date.now() };\n await saveStore(store);\n }\n return;\n }\n\n if (normalizedEventType === EventType.ViewProduct) {\n const rawId = props.id ?? props.items?.[0]?.item_id;\n const productId = normalizeId(rawId, idPrefix);\n if (!productId) return;\n const store = await loadStore();\n const entry = store[productId];\n if (entry && Date.now() - entry.ts <= EXPIRY_MS) {\n props.item_list_id = entry.source;\n if (Array.isArray(props.items)) {\n props.items = props.items.map((item) => ({ ...item, item_list_id: entry.source }));\n }\n }\n return;\n }\n\n if (normalizedEventType === EventType.AddToCart) {\n if (!Array.isArray(props.items)) return;\n const store = await loadStore();\n props.items = props.items.map((item) => {\n const productId = normalizeId(item.item_id, idPrefix);\n const entry = productId ? store[productId] : null;\n if (entry && Date.now() - entry.ts <= EXPIRY_MS) {\n return { ...item, item_list_id: entry.source };\n }\n return item;\n });\n const firstMatch = props.items.find((item) => item.item_list_id);\n if (firstMatch?.item_list_id) {\n props.item_list_id = firstMatch.item_list_id;\n }\n }\n}\n\nexport async function getAttribution(productId: string): Promise<string | null> {\n const store = await loadStore();\n const entry = store[String(productId)];\n if (entry && Date.now() - entry.ts < EXPIRY_MS) return entry.source;\n return null;\n}\n","import { GaEventType } from './constants';\nimport type { TrackProperties } from './types';\n\nfunction toSnakeCase(str: string): string {\n return str.replace(/-/g, '_');\n}\n\nexport interface GaSendOptions {\n gaProxyUrl: string;\n clientId: string;\n sessionId: string;\n numericSessionId: number;\n userId?: string | null;\n debug?: boolean;\n}\n\nexport async function sendToGA(\n eventType: string,\n props: TrackProperties,\n options: GaSendOptions\n): Promise<void> {\n const gaEvent = GaEventType[eventType] || toSnakeCase(eventType);\n const {\n items,\n currency,\n value,\n transaction_id,\n tax,\n shipping,\n coupon,\n ...rest\n } = props;\n\n const params: Record<string, unknown> = {\n session_id: options.numericSessionId,\n engagement_time_msec: 1,\n session_engaged: '1',\n };\n if (options.debug) params.debug_mode = true;\n\n if (currency) params.currency = currency;\n if (value !== undefined) params.value = value;\n if (transaction_id) params.transaction_id = transaction_id;\n if (tax !== undefined) params.tax = tax;\n if (shipping !== undefined) params.shipping = shipping;\n if (coupon) params.coupon = coupon;\n if (items) params.items = items;\n\n const passthroughKeys = [\n 'item_list_id',\n 'data_provider',\n 'event_source',\n 'id',\n 'search_term',\n 'total',\n 'total_text',\n 'total_vector',\n 'page_location',\n 'page_title',\n 'page_referrer',\n 'language',\n 'test_marker',\n 'yp_platform',\n 'yp_platform_version',\n 'yp_user_agent',\n ];\n for (const key of passthroughKeys) {\n if (rest[key] !== undefined) params[key] = rest[key];\n }\n\n const body: Record<string, unknown> = {\n client_id: options.clientId || options.sessionId,\n timestamp_micros: Date.now() * 1000,\n events: [{ name: gaEvent, params }],\n };\n\n if (options.userId) body.user_id = options.userId;\n\n const sep = options.gaProxyUrl.includes('?') ? '&' : '?';\n const url = options.debug\n ? `${options.gaProxyUrl}${sep}debug=1`\n : options.gaProxyUrl;\n\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n if (options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] GA MP → ${gaEvent} (status ${res.status})`);\n }\n } catch (e) {\n if (options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] GA MP error: ${(e as Error).message}`);\n }\n }\n}\n","import { Storage, StorageKeys } from './storage';\nimport type { ApiEvent } from './types';\n\nexport interface BeaconOptions {\n apiEndpoint: string;\n apiToken?: string | null;\n defaultParams?: Record<string, unknown>;\n idPrefix?: string;\n debounceMs?: number;\n debug?: boolean;\n}\n\nexport class Beacon {\n private queue: ApiEvent[] = [];\n private isSending = false;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(private options: BeaconOptions) {}\n\n enqueue(event: ApiEvent): void {\n this.queue.push(event);\n this.scheduleSend();\n }\n\n enqueueAll(events: ApiEvent[]): void {\n this.queue.push(...events);\n this.scheduleSend();\n }\n\n private scheduleSend(): void {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(() => {\n void this.send();\n }, this.options.debounceMs ?? 1000);\n }\n\n async send(retryCount = 0): Promise<void> {\n if (this.queue.length === 0) return;\n if (!this.options.apiEndpoint) return;\n if (this.isSending) return;\n\n this.isSending = true;\n const eventsToSend = this.queue.splice(0, this.queue.length);\n\n const events = eventsToSend.map((event) => {\n const merged: Record<string, unknown> = {\n ...event,\n ...(this.options.defaultParams ?? {}),\n };\n const rawId = (event.extra_data as Record<string, unknown>).id;\n if (rawId && this.options.idPrefix) {\n merged.extra_data = {\n ...event.extra_data,\n id: `${this.options.idPrefix}${rawId}`,\n };\n }\n return merged;\n });\n\n try {\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.options.apiToken) headers.Authorization = `Token ${this.options.apiToken}`;\n\n const res = await fetch(this.options.apiEndpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify(events),\n });\n\n if (res.status > 299) {\n throw new Error(`Failed to send events (status ${res.status})`);\n }\n\n if (this.options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] Sync: ${events.length} events sent`);\n }\n await Storage.removeItem(StorageKeys.PENDING_EVENTS);\n } catch (e) {\n if (this.options.debug) {\n // eslint-disable-next-line no-console\n console.log(`[YesPlz Analytics] Sync failed: ${(e as Error).message}`);\n }\n this.queue.unshift(...eventsToSend);\n this.isSending = false;\n if (retryCount < 1) {\n setTimeout(() => void this.send(retryCount + 1), 2000);\n }\n return;\n }\n\n this.isSending = false;\n if (this.queue.length > 0) this.scheduleSend();\n }\n\n async flush(): Promise<void> {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n await this.send();\n }\n\n async savePending(): Promise<void> {\n if (this.queue.length === 0) return;\n const toSave = this.queue.slice(-100);\n await Storage.setJSON(StorageKeys.PENDING_EVENTS, toSave);\n this.queue = [];\n }\n\n async restorePending(): Promise<void> {\n const pending = await Storage.getJSON<ApiEvent[]>(StorageKeys.PENDING_EVENTS, []);\n if (pending.length > 0) {\n this.queue.unshift(...pending);\n await Storage.removeItem(StorageKeys.PENDING_EVENTS);\n this.scheduleSend();\n }\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yesplz-ai/analytics-react-native",
3
- "version": "0.1.0",
4
- "description": "YesPlz Analytics SDK for React Native manual event tracking + interactions API + GA4 Measurement Protocol via shop proxy",
3
+ "version": "0.1.1",
4
+ "description": "YesPlz Analytics SDK for React Native - manual event tracking + interactions API + GA4 Measurement Protocol via shop proxy",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",
@@ -47,10 +47,10 @@
47
47
  "@babel/preset-typescript": "^7.24.0",
48
48
  "@react-native-async-storage/async-storage": "^2.0.0",
49
49
  "@types/jest": "^29.5.14",
50
- "@types/react": "^18.3.0",
50
+ "@types/react": "^18.2.0",
51
51
  "babel-jest": "^29.7.0",
52
52
  "jest": "^29.7.0",
53
- "react": "^18.3.0",
53
+ "react": "18.2.0",
54
54
  "react-native": "^0.74.0",
55
55
  "tsup": "^8.5.0",
56
56
  "typescript": "^5.6.0"