@bluenath/engage 2.0.5 → 2.0.8
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/README.md +28 -2
- package/dist/core/EventQueue.d.ts +8 -13
- package/dist/core/Transport.d.ts +6 -12
- package/dist/index.cjs +1 -1
- package/dist/index.js +22 -109
- package/dist/types/index.d.ts +1 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -50,11 +50,37 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
|
50
50
|
);
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
+
## Quick Start (Plain JavaScript / Non-React)
|
|
54
|
+
|
|
55
|
+
For non-React applications, you can import and initialize the core `Engage` instance directly.
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
import { engage } from "@bluenath/engage";
|
|
59
|
+
|
|
60
|
+
// Initialize once at the entry point of your app
|
|
61
|
+
engage.init({
|
|
62
|
+
writeKey: "YOUR_PUBLIC_WRITE_KEY",
|
|
63
|
+
tracking: {
|
|
64
|
+
autoTrack: true,
|
|
65
|
+
useCookies: true,
|
|
66
|
+
fingerprint: true
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Manual event tracking
|
|
71
|
+
engage.track("PURCHASE", {
|
|
72
|
+
amount: 2999,
|
|
73
|
+
currency: "INR",
|
|
74
|
+
orderId: "ORD-9981"
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
53
78
|
## Manual Event Tracking
|
|
54
79
|
|
|
55
|
-
Use the `useAnalytics` hook to capture specific business outcomes.
|
|
80
|
+
Use the `track` method (or `useAnalytics` hook in React) to capture specific business outcomes.
|
|
56
81
|
|
|
57
82
|
```tsx
|
|
83
|
+
// React Example
|
|
58
84
|
import { useAnalytics } from "@bluenath/engage";
|
|
59
85
|
|
|
60
86
|
export function PurchaseConfirmation() {
|
|
@@ -80,7 +106,7 @@ For accurate campaign attribution, ensure the `ref` field follows the standard E
|
|
|
80
106
|
|
|
81
107
|
## API Reference
|
|
82
108
|
|
|
83
|
-
###
|
|
109
|
+
### Configuration Options
|
|
84
110
|
|
|
85
111
|
| Property | Type | Required | Description |
|
|
86
112
|
| :--- | :--- | :--- | :--- |
|
|
@@ -1,34 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EngageEvent } from '../types';
|
|
2
2
|
import { Transport } from './Transport';
|
|
3
3
|
|
|
4
4
|
export declare class EventQueue {
|
|
5
|
-
private queue;
|
|
6
5
|
private engageQueue;
|
|
7
6
|
private storage;
|
|
8
7
|
private transport;
|
|
9
|
-
private readonly STORAGE_KEY;
|
|
10
8
|
private readonly ENGAGE_STORAGE_KEY;
|
|
11
9
|
private isFlushing;
|
|
12
10
|
private flushInterval;
|
|
13
|
-
private retryCount;
|
|
14
11
|
private readonly MAX_RETRIES;
|
|
15
12
|
constructor(transport: Transport);
|
|
16
13
|
private startTimer;
|
|
17
14
|
/**
|
|
18
|
-
* Enqueue a
|
|
15
|
+
* Enqueue a new EngageEvent (Spec §3.1).
|
|
16
|
+
* All events go through the authenticated /api/v1/analytics/ingest endpoint.
|
|
19
17
|
*/
|
|
20
|
-
|
|
18
|
+
enqueueEngageEvent(event: EngageEvent): void;
|
|
21
19
|
/**
|
|
22
|
-
*
|
|
20
|
+
* Legacy compatibility stub.
|
|
21
|
+
* The old /tracking/ingest endpoint caused 401s with the write key format.
|
|
22
|
+
* Events are already dual-tracked via emitEngageEvent() in Analytics.ts.
|
|
23
23
|
*/
|
|
24
|
-
|
|
25
|
-
private save;
|
|
24
|
+
enqueue(_event: any): void;
|
|
26
25
|
private saveEngage;
|
|
27
26
|
private load;
|
|
28
|
-
/**
|
|
29
|
-
* Flush legacy events (existing behavior)
|
|
30
|
-
*/
|
|
31
|
-
flush(): Promise<void>;
|
|
32
27
|
/**
|
|
33
28
|
* Spec §3.4: Flush EngageEvent[] with exponential backoff retry.
|
|
34
29
|
* Max 3 retries with 1s/2s/4s backoff. Drop batch after 3 failures.
|
package/dist/core/Transport.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EngageEvent } from '../types';
|
|
2
2
|
|
|
3
3
|
export interface TransportResult {
|
|
4
4
|
success: boolean;
|
|
@@ -9,25 +9,19 @@ export declare class Transport {
|
|
|
9
9
|
private endpoints;
|
|
10
10
|
private apiKey;
|
|
11
11
|
constructor(endpoints: {
|
|
12
|
-
legacy: string;
|
|
13
12
|
engage: string;
|
|
14
13
|
});
|
|
15
14
|
setApiKey(key: string): void;
|
|
16
15
|
/**
|
|
17
|
-
* Sends
|
|
18
|
-
*
|
|
19
|
-
*/
|
|
20
|
-
send(events: AnalyticsEvent[]): Promise<boolean>;
|
|
21
|
-
/**
|
|
22
|
-
* Sends new EngageEvent[] to the ingest endpoint (Spec §4.1).
|
|
23
|
-
* Returns detailed result for retry logic.
|
|
16
|
+
* Sends EngageEvent[] to the ingest endpoint (Spec §4.1).
|
|
17
|
+
* Uses Bearer auth header. Returns detailed result for retry logic.
|
|
24
18
|
*/
|
|
25
19
|
sendEngageEvents(events: EngageEvent[]): Promise<TransportResult>;
|
|
26
20
|
private sendRaw;
|
|
27
21
|
/**
|
|
28
22
|
* Uses sendBeacon for last-resort page unload flush.
|
|
29
|
-
*
|
|
30
|
-
*
|
|
23
|
+
* Note: sendBeacon cannot send custom headers (no Authorization).
|
|
24
|
+
* The ingest endpoint accepts unauthenticated beacon payloads as best-effort.
|
|
31
25
|
*/
|
|
32
|
-
beaconFlush(payload: string
|
|
26
|
+
beaconFlush(payload: string): boolean;
|
|
33
27
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=Object.defineProperty,i=(i,t,a)=>((i,t,a)=>t in i?e(i,t,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[t]=a)(i,"symbol"!=typeof t?t+"":t,a);Object.defineProperties(exports,{i:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("react/jsx-runtime"),a=require("react");let n;const r=new Uint8Array(16);function s(){if(!n&&(n="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!n))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return n(r)}const o=[];for(let I=0;I<256;++I)o.push((I+256).toString(16).slice(1));const c={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function u(e,i,t){if(c.randomUUID&&!e)return c.randomUUID();const a=(e=e||{}).random||(e.rng||s)();return a[6]=15&a[6]|64,a[8]=63&a[8]|128,function(e,i=0){return o[e[i+0]]+o[e[i+1]]+o[e[i+2]]+o[e[i+3]]+"-"+o[e[i+4]]+o[e[i+5]]+"-"+o[e[i+6]]+o[e[i+7]]+"-"+o[e[i+8]]+o[e[i+9]]+"-"+o[e[i+10]]+o[e[i+11]]+o[e[i+12]]+o[e[i+13]]+o[e[i+14]]+o[e[i+15]]}(a)}const d=e=>{let i=2166136261;const t=e.length;for(let a=0;a<t;a++)i^=e.charCodeAt(a),i+=(i<<1)+(i<<4)+(i<<7)+(i<<8)+(i<<24);return("0000000"+(i>>>0).toString(16)).substr(-8)};class h{constructor(e="local"){i(this,"memoryStore",{}),i(this,"keyPrefix","engage_"),i(this,"domain"),this.type=e,this.domain=this.getCookieDomain()}getItem(e){const i=this.keyPrefix+e;if(this.memoryStore.hasOwnProperty(i))return this.memoryStore[i];try{if("local"===this.type&&this.isBrowser())return window.localStorage.getItem(i);if("cookie"===this.type&&this.isBrowser())return this.getCookie(i)}catch(t){return null}return null}setItem(e,i){const t=this.keyPrefix+e;this.memoryStore[t]=i;try{"local"===this.type&&this.isBrowser()?window.localStorage.setItem(t,i):"cookie"===this.type&&this.isBrowser()&&this.setCookie(t,i,365)}catch(a){this.isQuotaError(a)&&(this.type="memory")}}removeItem(e){const i=this.keyPrefix+e;delete this.memoryStore[i];try{"local"===this.type&&this.isBrowser()?window.localStorage.removeItem(i):"cookie"===this.type&&this.isBrowser()&&this.setCookie(i,"",-1)}catch(t){}}getCookie(e){const i=e+"=",t=document.cookie.split(";");for(let a=0;a<t.length;a++){let e=t[a];for(;" "===e.charAt(0);)e=e.substring(1,e.length);if(0===e.indexOf(i))return decodeURIComponent(e.substring(i.length,e.length))}return null}setCookie(e,i,t){let a="";if(t){const e=new Date;e.setTime(e.getTime()+24*t*60*60*1e3),a="; expires="+e.toUTCString()}document.cookie=`${e}=${encodeURIComponent(i)}${a}; path=/; domain=${this.domain}; SameSite=Lax; Secure`}getCookieDomain(){if(!this.isBrowser())return"";const e=window.location.hostname,i=e.split(".");return 1===i.length||"localhost"===e?"":i.length>2?"."+i.slice(-2).join("."):"."+e}isBrowser(){try{return"undefined"!=typeof window&&void 0!==window.document}catch(e){return!1}}isQuotaError(e){return e instanceof DOMException&&(22===e.code||1014===e.code||"QuotaExceededError"===e.name||"NS_ERROR_DOM_QUOTA_REACHED"===e.name)}}class l{constructor(e){i(this,"storage"),i(this,"SESSION_TIMEOUT",18e5),i(this,"deviceId"),i(this,"sessionId"),i(this,"userId",null),i(this,"currentUrl"),i(this,"referrer"),this.storage=new h(e.persistence),this.deviceId=this.getOrSetDeviceId(),this.sessionId="",this.manageSession(),"undefined"!=typeof window?(this.currentUrl=window.location.href,this.referrer=document.referrer,this.listenToHistory()):(this.currentUrl="",this.referrer="")}getOrSetDeviceId(){const e=this.storage.getItem("device_id");if(e)return e;const i=(()=>{if("undefined"==typeof window)return"server-side-id";const e=navigator,i=window.screen,t={userAgent:e.userAgent||"",screenRes:`${i.width}x${i.height}`,colorDepth:i.colorDepth||0,timezone:(new Date).getTimezoneOffset(),language:e.language||"en-US",platform:e.platform||"unknown",hardwareConcurrency:e.hardwareConcurrency||1,deviceMemory:e.deviceMemory||0},a=[t.platform,t.language,t.screenRes,t.colorDepth,t.timezone,t.hardwareConcurrency,t.deviceMemory].join("|");return`${d(a)}-${d(t.userAgent)}`})();return this.storage.setItem("device_id",i),i}manageSession(){const e=Date.now(),i=this.storage.getItem("session_id"),t=parseInt(this.storage.getItem("last_activity")||"0");if(!i||e-t>this.SESSION_TIMEOUT?(this.sessionId=`sess_${e}_${Math.random().toString(36).substr(2,9)}`,this.storage.setItem("session_id",this.sessionId)):this.sessionId=i,this.storage.setItem("last_activity",e.toString()),"undefined"!=typeof window){const e=()=>this.storage.setItem("last_activity",Date.now().toString());window.addEventListener("click",e),window.addEventListener("scroll",e)}}listenToHistory(){const e=history.pushState;history.pushState=(...i)=>{e.apply(history,i),this.handleUrlChange()},window.addEventListener("popstate",()=>this.handleUrlChange())}handleUrlChange(){const e=window.location.href;e!==this.currentUrl&&(this.referrer=this.currentUrl,this.currentUrl=e)}getPayload(){var e;return{library:{name:"@engagepro/analytics",version:"2.0.0"},user:{anonymousId:this.deviceId,id:this.userId},session:{id:this.sessionId,startTime:parseInt(this.sessionId.split("_")[1]||Date.now().toString())},page:{path:"undefined"!=typeof window?window.location.pathname:"",referrer:this.referrer,title:"undefined"!=typeof document?document.title:"",search:"undefined"!=typeof window?window.location.search:"",url:this.currentUrl},network:{online:"undefined"==typeof navigator||navigator.onLine,downlink:null==(e=navigator.connection)?void 0:e.downlink},screen:{width:"undefined"!=typeof screen?screen.width:0,height:"undefined"!=typeof screen?screen.height:0,density:"undefined"!=typeof window?window.devicePixelRatio:1},device:{fingerprint:this.deviceId,type:this.getDeviceType(),userAgent:"undefined"!=typeof navigator?navigator.userAgent:"server"},locale:"undefined"!=typeof navigator?navigator.language:"en-US",timezone:Intl.DateTimeFormat().resolvedOptions().timeZone}}getDeviceType(){if("undefined"==typeof navigator)return"desktop";const e=navigator.userAgent;return/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(e)?"tablet":/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated/.test(e)?"mobile":"desktop"}}class A{constructor(e){i(this,"queue",[]),i(this,"engageQueue",[]),i(this,"storage"),i(this,"transport"),i(this,"STORAGE_KEY","engage_queue_v1"),i(this,"ENGAGE_STORAGE_KEY","engage_events_v2"),i(this,"isFlushing",!1),i(this,"flushInterval"),i(this,"retryCount",0),i(this,"MAX_RETRIES",3),this.transport=e,this.storage=new h("local"),this.load(),"undefined"!=typeof window&&(window.addEventListener("online",()=>{this.retryCount=0,this.flush()}),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&this.flushBeacon()}),window.addEventListener("beforeunload",()=>{this.flushBeacon()})),this.startTimer()}startTimer(){this.flushInterval&&clearInterval(this.flushInterval),this.flushInterval=setInterval(()=>{this.flush()},5e3)}enqueue(e){this.queue.push(e),this.save(),(this.queue.length>=10||"PURCHASE"===e.standardEvent)&&this.flush()}enqueueEngageEvent(e){this.engageQueue.push(e),this.saveEngage(),this.engageQueue.length>=10&&this.flushEngageEvents()}save(){this.storage.setItem(this.STORAGE_KEY,JSON.stringify(this.queue))}saveEngage(){this.storage.setItem(this.ENGAGE_STORAGE_KEY,JSON.stringify(this.engageQueue))}load(){const e=this.storage.getItem(this.STORAGE_KEY);if(e)try{this.queue=JSON.parse(e)}catch(t){this.queue=[]}const i=this.storage.getItem(this.ENGAGE_STORAGE_KEY);if(i)try{this.engageQueue=JSON.parse(i)}catch(t){this.engageQueue=[]}}async flush(){if(0===this.queue.length||this.isFlushing)return void(this.engageQueue.length>0&&!this.isFlushing&&await this.flushEngageEvents());if("undefined"!=typeof navigator&&!navigator.onLine)return;this.isFlushing=!0;const e=[...this.queue];this.queue=[],this.save();try{if(!(await this.transport.send(e)))throw new Error("Server rejected batch");this.retryCount=0}catch(i){this.queue=[...e,...this.queue],this.save(),this.retryCount++}finally{this.isFlushing=!1}this.engageQueue.length>0&&await this.flushEngageEvents()}async flushEngageEvents(){if(0===this.engageQueue.length||this.isFlushing)return;if("undefined"!=typeof navigator&&!navigator.onLine)return;this.isFlushing=!0;const e=[...this.engageQueue];this.engageQueue=[],this.saveEngage();let i=0,t=!1;for(;i<this.MAX_RETRIES&&!t;){const a=await this.transport.sendEngageEvents(e);if(a.success){t=!0;break}if(a.permanent)return void(this.isFlushing=!1);if(i++,i<this.MAX_RETRIES){const e=1e3*Math.pow(2,i-1);await new Promise(i=>setTimeout(i,e))}}this.isFlushing=!1}flushBeacon(){if(this.queue.length>0){const e=JSON.stringify({batch:this.queue,sentAt:(new Date).toISOString()});this.transport.beaconFlush(e,"legacy")&&(this.queue=[],this.save())}if(this.engageQueue.length>0){const e=JSON.stringify({events:this.engageQueue});this.transport.beaconFlush(e,"engage")&&(this.engageQueue=[],this.saveEngage())}}}class f{constructor(e){i(this,"apiKey",""),this.endpoints=e}setApiKey(e){this.apiKey=e}async send(e){return(await this.sendRaw(JSON.stringify({batch:e,sentAt:(new Date).toISOString()}),this.endpoints.legacy)).success}async sendEngageEvents(e){const i=JSON.stringify({events:e});return this.sendRaw(i,this.endpoints.engage)}async sendRaw(e,i){const t={"Content-Type":"application/json"};if(this.apiKey&&(t.Authorization=`Bearer ${this.apiKey}`),!this.apiKey&&"undefined"!=typeof navigator&&navigator.sendBeacon&&e.length<6e4){const t=new Blob([e],{type:"application/json"});if(navigator.sendBeacon(i,t))return{success:!0,permanent:!1}}try{const a=await fetch(i,{method:"POST",headers:t,body:e,keepalive:!0});return 401===a.status||422===a.status?{success:!1,permanent:!0,status:a.status}:{success:a.ok||202===a.status,permanent:!1,status:a.status}}catch(a){return{success:!1,permanent:!1}}}beaconFlush(e,i){if("undefined"==typeof navigator||!navigator.sendBeacon)return!1;const t="legacy"===i?this.endpoints.legacy:this.endpoints.engage,a=new Blob([e],{type:"application/json"});return navigator.sendBeacon(t,a)}}const p={"Asia/Kolkata":"IN","Asia/Calcutta":"IN","Asia/Mumbai":"IN","Asia/Dhaka":"BD","Asia/Kathmandu":"NP","Asia/Colombo":"LK","Asia/Karachi":"PK","Asia/Kabul":"AF","Asia/Tehran":"IR","Asia/Dubai":"AE","Asia/Muscat":"OM","Asia/Bahrain":"BH","Asia/Qatar":"QA","Asia/Kuwait":"KW","Asia/Riyadh":"SA","Asia/Aden":"YE","Asia/Baghdad":"IQ","Asia/Amman":"JO","Asia/Beirut":"LB","Asia/Damascus":"SY","Asia/Jerusalem":"IL","Asia/Tel_Aviv":"IL","Asia/Nicosia":"CY","Asia/Tokyo":"JP","Asia/Seoul":"KR","Asia/Pyongyang":"KP","Asia/Shanghai":"CN","Asia/Chongqing":"CN","Asia/Harbin":"CN","Asia/Urumqi":"CN","Asia/Hong_Kong":"HK","Asia/Macau":"MO","Asia/Taipei":"TW","Asia/Singapore":"SG","Asia/Kuala_Lumpur":"MY","Asia/Brunei":"BN","Asia/Jakarta":"ID","Asia/Makassar":"ID","Asia/Jayapura":"ID","Asia/Bangkok":"TH","Asia/Ho_Chi_Minh":"VN","Asia/Saigon":"VN","Asia/Phnom_Penh":"KH","Asia/Vientiane":"LA","Asia/Yangon":"MM","Asia/Rangoon":"MM","Asia/Manila":"PH","Asia/Ulaanbaatar":"MN","Asia/Hovd":"MN","Asia/Tbilisi":"GE","Asia/Baku":"AZ","Asia/Yerevan":"AM","Asia/Almaty":"KZ","Asia/Bishkek":"KG","Asia/Tashkent":"UZ","Asia/Ashgabat":"TM","Asia/Dushanbe":"TJ","Asia/Thimphu":"BT","Asia/Dili":"TL","Europe/London":"GB","Europe/Dublin":"IE","Europe/Lisbon":"PT","Europe/Madrid":"ES","Europe/Paris":"FR","Europe/Brussels":"BE","Europe/Amsterdam":"NL","Europe/Luxembourg":"LU","Europe/Berlin":"DE","Europe/Zurich":"CH","Europe/Vienna":"AT","Europe/Rome":"IT","Europe/Monaco":"MC","Europe/Vatican":"VA","Europe/Malta":"MT","Europe/Prague":"CZ","Europe/Budapest":"HU","Europe/Warsaw":"PL","Europe/Bratislava":"SK","Europe/Ljubljana":"SI","Europe/Zagreb":"HR","Europe/Belgrade":"RS","Europe/Sarajevo":"BA","Europe/Podgorica":"ME","Europe/Skopje":"MK","Europe/Tirane":"AL","Europe/Sofia":"BG","Europe/Bucharest":"RO","Europe/Chisinau":"MD","Europe/Athens":"GR","Europe/Istanbul":"TR","Europe/Helsinki":"FI","Europe/Stockholm":"SE","Europe/Oslo":"NO","Europe/Copenhagen":"DK","Europe/Tallinn":"EE","Europe/Riga":"LV","Europe/Vilnius":"LT","Europe/Minsk":"BY","Europe/Moscow":"RU","Europe/Kaliningrad":"RU","Europe/Samara":"RU","Europe/Kiev":"UA","Europe/Kyiv":"UA","Europe/Reykjavik":"IS","Europe/Andorra":"AD","Europe/Gibraltar":"GI","Europe/San_Marino":"SM","America/New_York":"US","America/Chicago":"US","America/Denver":"US","America/Los_Angeles":"US","America/Phoenix":"US","America/Anchorage":"US","Pacific/Honolulu":"US","America/Detroit":"US","America/Indianapolis":"US","America/Boise":"US","America/Juneau":"US","America/Adak":"US","America/Toronto":"CA","America/Vancouver":"CA","America/Montreal":"CA","America/Winnipeg":"CA","America/Edmonton":"CA","America/Halifax":"CA","America/St_Johns":"CA","America/Regina":"CA","America/Mexico_City":"MX","America/Cancun":"MX","America/Tijuana":"MX","America/Monterrey":"MX","America/Hermosillo":"MX","America/Guatemala":"GT","America/Belize":"BZ","America/El_Salvador":"SV","America/Tegucigalpa":"HN","America/Managua":"NI","America/Costa_Rica":"CR","America/Panama":"PA","America/Bogota":"CO","America/Lima":"PE","America/Guayaquil":"EC","America/Caracas":"VE","America/La_Paz":"BO","America/Asuncion":"PY","America/Montevideo":"UY","America/Buenos_Aires":"AR","America/Argentina/Buenos_Aires":"AR","America/Santiago":"CL","America/Sao_Paulo":"BR","America/Recife":"BR","America/Manaus":"BR","America/Fortaleza":"BR","America/Bahia":"BR","America/Havana":"CU","America/Jamaica":"JM","America/Port-au-Prince":"HT","America/Santo_Domingo":"DO","America/Puerto_Rico":"PR","America/Port_of_Spain":"TT","America/Barbados":"BB","America/Martinique":"MQ","America/Guyana":"GY","America/Paramaribo":"SR","America/Cayenne":"GF","America/Curacao":"CW","Africa/Cairo":"EG","Africa/Casablanca":"MA","Africa/Tunis":"TN","Africa/Algiers":"DZ","Africa/Tripoli":"LY","Africa/Khartoum":"SD","Africa/Addis_Ababa":"ET","Africa/Nairobi":"KE","Africa/Dar_es_Salaam":"TZ","Africa/Kampala":"UG","Africa/Mogadishu":"SO","Africa/Lagos":"NG","Africa/Accra":"GH","Africa/Abidjan":"CI","Africa/Dakar":"SN","Africa/Bamako":"ML","Africa/Ouagadougou":"BF","Africa/Conakry":"GN","Africa/Freetown":"SL","Africa/Monrovia":"LR","Africa/Lome":"TG","Africa/Porto-Novo":"BJ","Africa/Niamey":"NE","Africa/Douala":"CM","Africa/Libreville":"GA","Africa/Bangui":"CF","Africa/Brazzaville":"CG","Africa/Kinshasa":"CD","Africa/Lubumbashi":"CD","Africa/Luanda":"AO","Africa/Maputo":"MZ","Africa/Harare":"ZW","Africa/Lusaka":"ZM","Africa/Lilongwe":"MW","Africa/Johannesburg":"ZA","Africa/Windhoek":"NA","Africa/Gaborone":"BW","Africa/Maseru":"LS","Africa/Mbabane":"SZ","Indian/Antananarivo":"MG","Indian/Mauritius":"MU","Indian/Reunion":"RE","Indian/Comoro":"KM","Indian/Mayotte":"YT","Africa/Djibouti":"DJ","Africa/Asmara":"ER","Australia/Sydney":"AU","Australia/Melbourne":"AU","Australia/Brisbane":"AU","Australia/Perth":"AU","Australia/Adelaide":"AU","Australia/Hobart":"AU","Australia/Darwin":"AU","Australia/Lord_Howe":"AU","Pacific/Auckland":"NZ","Pacific/Chatham":"NZ","Pacific/Fiji":"FJ","Pacific/Tongatapu":"TO","Pacific/Apia":"WS","Pacific/Port_Moresby":"PG","Pacific/Noumea":"NC","Pacific/Guam":"GU","Pacific/Pago_Pago":"AS","Pacific/Tahiti":"PF","Atlantic/Reykjavik":"IS","Atlantic/Azores":"PT","Atlantic/Canary":"ES","Atlantic/Madeira":"PT","Atlantic/Cape_Verde":"CV","Atlantic/Bermuda":"BM","Indian/Maldives":"MV","Indian/Chagos":"IO","Indian/Christmas":"CX","Indian/Cocos":"CC"},m=new Set(["localhost","127.0.0.1"]),g="engage_session_id",y={$:"USD",US$:"USD",USD:"USD","₹":"INR",RS:"INR","RS.":"INR",INR:"INR","€":"EUR",EUR:"EUR","£":"GBP",GBP:"GBP","¥":"JPY",JPY:"JPY"},v=(e,i,t)=>{if(!e)return t;try{const a=new URL(e);return a.hostname.endsWith("bluenath.com")||m.has(a.hostname)?(a.pathname=i,a.search="",a.hash="",a.toString()):t}catch{return t}},w=e=>{if("string"!=typeof e)return;const i=e.trim().toUpperCase();return i?y[i]?y[i]:i.includes("₹")||i.startsWith("RS")?"INR":i.includes("$")&&!i.includes("CAD")?"USD":i.includes("€")?"EUR":i.includes("£")?"GBP":i.includes("¥")?"JPY":/^[A-Z]{3}$/.test(i)?i:void 0:void 0};function E(e){if(!e||"object"!=typeof e)return;const i={},t=Object.keys(e).slice(0,20);for(const a of t){const t=e[a];"boolean"==typeof t||"number"==typeof t?i[a]=t:"string"==typeof t&&(i[a]=t.slice(0,100))}return Object.keys(i).length>0?i:void 0}class S{constructor(e){i(this,"config"),i(this,"context"),i(this,"queue"),i(this,"transport"),i(this,"sessionId"),i(this,"countryCode"),i(this,"currentSentiment"),i(this,"identify",(e,i)=>{this.context.userId=e,this.processEvent({event:"Identify",properties:{traits:i},standardEvent:"LOGIN",intent:"identity",confidence:1})}),i(this,"page",(e,i)=>{const t=this.context.getPayload().page;this.processEvent({event:e||t.title||"Unknown Page",properties:{path:t.path,referrer:t.referrer,title:t.title,...i},standardEvent:"PAGE_VIEW",intent:"navigation",confidence:1}),this.emitEngageEvent("pageview",i)}),i(this,"track",(e,i,t)=>{this.processEvent({event:e,properties:i||{},...t});const a={purchase:"purchase",PURCHASE:"purchase",signup:"signup",SIGNUP:"signup",register:"signup",REGISTER:"signup",add_to_cart:"add_to_cart",ADD_TO_CART:"add_to_cart",product_view:"product_view",VIEW_CONTENT:"product_view",session_start:"session_start",session_end:"session_end"},n=a[e]||a[(null==t?void 0:t.standardEvent)||""]||"custom";this.emitEngageEvent(n,i)}),i(this,"trackRevenue",(e,i,t)=>{const a=Math.max(0,(e=>{if("number"==typeof e)return Number.isFinite(e)?e:0;const i=e.trim().replace(/[^0-9.+-]/g,""),t=Number(i);return Number.isFinite(t)?t:0})(e)),n=w(null==i?void 0:i.currency)||w(null==i?void 0:i.currencyCode)||w(null==i?void 0:i.currencySymbol)||("string"==typeof e?w(e):void 0)||"USD";this.track("PURCHASE",{...i||{},value:a,amount:a,valuePaise:Math.round(100*a),amountPaise:Math.round(100*a),currency:n,currencyCode:n},{standardEvent:"PURCHASE",intent:"commerce",confidence:1,...t})}),i(this,"setSentiment",e=>{this.currentSentiment=e}),this.config=e;const t=e.apiKey||e.writeKey,a=v(e.apiHost,"/api/v1/tracking/ingest","https://engage-api.bluenath.com/api/v1/tracking/ingest"),n=v(e.apiHost,"/api/v1/analytics/ingest","https://engage-api.bluenath.com/api/v1/analytics/ingest");this.transport=new f({legacy:a,engage:n}),this.transport.setApiKey(t),this.context=new l({persistence:e.tracking.useCookies?"cookie":"local"}),this.queue=new A(this.transport),this.sessionId=function(){if("undefined"==typeof sessionStorage)return u();let e=sessionStorage.getItem(g);return e||(e=u(),sessionStorage.setItem(g,e)),e}(),this.countryCode=function(){try{const e=Intl.DateTimeFormat().resolvedOptions().timeZone;if(!e)return;return p[e]}catch{return}}(),e.tracking.autoTrack&&"undefined"!=typeof window&&this.page()}emitEngageEvent(e,i){const t=this.context.getPayload().page,a={type:e,timestamp:(new Date).toISOString(),sessionId:this.sessionId,userId:this.context.getPayload().user.id||void 0,countryCode:this.countryCode,sentiment:this.currentSentiment,referrer:(t.referrer||"").slice(0,500),path:t.path||("undefined"!=typeof window?window.location.pathname:"/"),currency:w(null==i?void 0:i.currency)||w(null==i?void 0:i.currencyCode)||void 0,amount:"number"==typeof(null==i?void 0:i.amountPaise)?i.amountPaise:"number"==typeof(null==i?void 0:i.amount)?Math.round(100*i.amount):void 0,productId:"string"==typeof(null==i?void 0:i.productId)?i.productId:void 0,productName:"string"==typeof(null==i?void 0:i.productName)?i.productName:void 0,productCategory:"string"==typeof(null==i?void 0:i.productCategory)?i.productCategory:void 0,metadata:E(null==i?void 0:i.metadata)};this.queue.enqueueEngageEvent(a),this.currentSentiment&&(this.currentSentiment=void 0)}parseRef(e){if(!e)return{};const i=e.match(/^camp_([^_]+)_cr_([^_]+)$/);return i?{campaignId:i[1],creatorId:i[2]}:{}}processEvent(e){const i=this.context.getPayload(),t=e.properties.ref,a=("string"==typeof t?t:void 0)||new URLSearchParams(i.page.search||"").get("ref")||void 0,n=this.parseRef(a),r=e.properties.value??e.properties.amount??e.properties.valuePaise??e.properties.amountPaise,s=Number(r),o=e.properties.campaignId,c=e.properties.creatorId,d=e.properties.currency,h={event:e.event,properties:e.properties,standardEvent:e.standardEvent,intent:e.intent,confidence:e.confidence,rawLabel:e.rawLabel,timestamp:(new Date).toISOString(),messageId:u(),writeKey:this.config.writeKey||this.config.apiKey||"",ref:a,campaignId:("string"==typeof o?o:void 0)||n.campaignId,creatorId:("string"==typeof c?c:void 0)||n.creatorId,value:Number.isFinite(s)?Math.round(s):void 0,valuePaise:Number.isFinite(s)?Math.round(100*s):void 0,currency:("string"==typeof d?d:void 0)||"USD",userId:i.user.id||void 0,anonymousId:i.user.anonymousId,context:i};this.config.debug,this.queue.enqueue(h)}}class b{constructor(e){i(this,"analytics"),i(this,"metrics",{}),this.analytics=e,"undefined"!=typeof window&&"PerformanceObserver"in window&&this.observe()}observe(){try{new PerformanceObserver(e=>{for(const i of e.getEntries()){const e=i;e.hadRecentInput||(this.metrics.cls=(this.metrics.cls||0)+e.value)}}).observe({type:"layout-shift",buffered:!0}),new PerformanceObserver(e=>{const i=e.getEntries(),t=i[i.length-1];this.metrics.lcp=t.renderTime||t.loadTime,this.logMetric("LCP",this.metrics.lcp)}).observe({type:"largest-contentful-paint",buffered:!0}),new PerformanceObserver(e=>{const i=e.getEntries()[0];i&&(this.metrics.fid=i.processingStart-i.startTime,this.logMetric("FID",this.metrics.fid))}).observe({type:"first-input",buffered:!0}),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&this.metrics.cls&&this.logMetric("CLS",this.metrics.cls)})}catch(e){}}logMetric(e,i){i<0||this.analytics.track(`Core Web Vital: ${e}`,{metric:e,value:Math.round(i)},{standardEvent:"PERFORMANCE",intent:"performance",confidence:1,rawLabel:`${e}: ${Math.round(i)}ms`})}}const C=a.createContext(null);let R=null;const M=e=>{if(!R){const i={...e,writeKey:e.writeKey||e.apiKey||"",apiKey:e.apiKey||e.writeKey||""};R=new S(i)}return R},_={init:e=>M({writeKey:e.apiKey,apiKey:e.apiKey,apiHost:e.apiHost,tracking:e.tracking||{useCookies:!0,fingerprint:!0,autoTrack:!0},debug:e.debug}),track(e,i){R&&R.track(e,i)},page(e,i){R&&R.page(e,i)},identify(e,i){R&&R.identify(e,i)},trackRevenue(e,i){R&&R.trackRevenue(e,i)},setSentiment(e){R&&R.setSentiment(e)}};exports.EngageProProvider=({children:e,...i})=>{const n=a.useRef(null),r=a.useRef(null);n.current||(n.current=new S(i),"undefined"!=typeof window&&new b(n.current));const s=n.current;return a.useEffect(()=>{if(!i.tracking.autoTrack)return;const e=e=>{const i=e.target.closest('button, a, input[type="submit"], [data-track], .clickable');if(i){const e=Date.now(),t=r.current;t&&t.el===i&&e-t.ts<500?(t.count++,t.ts=e,3===t.count&&(s.track("Rage Click detected",{element:i.tagName},{standardEvent:"RAGE_CLICK",intent:"frustration",confidence:1}),r.current=null)):r.current={el:i,count:1,ts:e};const a=(e=>{let i=(e.innerText||e.value||e.getAttribute("aria-label")||"").trim();if(!i){const t=e.querySelector("img");t&&t.alt&&(i=t.alt);const a=e.querySelector("title");a&&(i=a.textContent||"")}const t=i.slice(0,100),a=t.toLowerCase(),n=(e.id||"").toLowerCase(),r=e.href||"";return/add to (cart|bag)|buy now/.test(a)||n.includes("add-to-cart")?{standard:"ADD_TO_CART",intent:"commerce",label:t,confidence:.9}:/checkout|proceed/.test(a)||r.includes("/checkout")?{standard:"INITIATE_CHECKOUT",intent:"commerce",label:t,confidence:.9}:/place order|pay now/.test(a)||n.includes("place-order")?{standard:"PURCHASE",intent:"commerce",label:t,confidence:.95}:/cancel order/.test(a)||n.includes("cancel")?{standard:"ORDER_CANCEL",intent:"lifecycle",label:t,confidence:.85}:/refund|return/.test(a)||n.includes("refund")?{standard:"ORDER_REFUND",intent:"lifecycle",label:t,confidence:.85}:/track package|shipping/.test(a)?{standard:"TRACK_PACKAGE",intent:"lifecycle",label:t,confidence:.8}:/write review/.test(a)||a.includes("star")&&/^[1-5]/.test(a)?{standard:"RATE_PRODUCT",intent:"engagement",label:t,confidence:.8}:a.includes("search")||n.includes("search")?{standard:"SEARCH",intent:"search",label:t,confidence:.7}:{standard:"GENERIC",intent:"interaction",label:t,confidence:.5}})(i),n="A"===i.tagName;s.track("Interaction",{element:i.tagName.toLowerCase(),id:i.id,destination:n?i.href:void 0},{standardEvent:a.standard,intent:a.intent,rawLabel:a.label,confidence:a.confidence})}},t=e=>{const i=e.target;(e=>"password"===e.getAttribute("type")||"hidden"===e.getAttribute("type")||/password|cvc|card|cc-num|ssn|credit|hidden/i.test(e.getAttribute("name")||e.id||""))(i)||"focusin"!==e.type||i.dataset.tracked||(i.dataset.tracked="true",s.track("Form Start",{field:i.name||i.id},{standardEvent:"FORM_START",intent:"identity"}))},a=()=>{const e=new URLSearchParams(window.location.search);e.has("q")&&s.track("Search Query",{query:e.get("q")},{standardEvent:"SEARCH",intent:"search"}),requestAnimationFrame(()=>s.page())},n=history.pushState;return history.pushState=(...e)=>{n.apply(history,e),a()},window.addEventListener("popstate",a),window.addEventListener("click",e,!0),window.addEventListener("focusin",t,!0),a(),()=>{history.pushState=n,window.removeEventListener("popstate",a),window.removeEventListener("click",e,!0),window.removeEventListener("focusin",t,!0)}},[i.tracking.autoTrack]),t.jsx(C.Provider,{value:s,children:e})},exports.default=S,exports.engage=_,exports.init=M,exports.useAnalytics=()=>{const e=a.useContext(C);if(!e)throw new Error("useAnalytics must be used within EngageProProvider");return e};
|
|
1
|
+
"use strict";var e=Object.defineProperty,i=(i,t,a)=>((i,t,a)=>t in i?e(i,t,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[t]=a)(i,"symbol"!=typeof t?t+"":t,a);Object.defineProperties(exports,{i:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("react/jsx-runtime"),a=require("react");let n;const r=new Uint8Array(16);function s(){if(!n&&(n="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!n))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return n(r)}const o=[];for(let _=0;_<256;++_)o.push((_+256).toString(16).slice(1));const c={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function u(e,i,t){if(c.randomUUID&&!e)return c.randomUUID();const a=(e=e||{}).random||(e.rng||s)();return a[6]=15&a[6]|64,a[8]=63&a[8]|128,function(e,i=0){return o[e[i+0]]+o[e[i+1]]+o[e[i+2]]+o[e[i+3]]+"-"+o[e[i+4]]+o[e[i+5]]+"-"+o[e[i+6]]+o[e[i+7]]+"-"+o[e[i+8]]+o[e[i+9]]+"-"+o[e[i+10]]+o[e[i+11]]+o[e[i+12]]+o[e[i+13]]+o[e[i+14]]+o[e[i+15]]}(a)}const d=e=>{let i=2166136261;const t=e.length;for(let a=0;a<t;a++)i^=e.charCodeAt(a),i+=(i<<1)+(i<<4)+(i<<7)+(i<<8)+(i<<24);return("0000000"+(i>>>0).toString(16)).substr(-8)};class h{constructor(e="local"){i(this,"memoryStore",{}),i(this,"keyPrefix","engage_"),i(this,"domain"),this.type=e,this.domain=this.getCookieDomain()}getItem(e){const i=this.keyPrefix+e;if(this.memoryStore.hasOwnProperty(i))return this.memoryStore[i];try{if("local"===this.type&&this.isBrowser())return window.localStorage.getItem(i);if("cookie"===this.type&&this.isBrowser())return this.getCookie(i)}catch(t){return null}return null}setItem(e,i){const t=this.keyPrefix+e;this.memoryStore[t]=i;try{"local"===this.type&&this.isBrowser()?window.localStorage.setItem(t,i):"cookie"===this.type&&this.isBrowser()&&this.setCookie(t,i,365)}catch(a){this.isQuotaError(a)&&(this.type="memory")}}removeItem(e){const i=this.keyPrefix+e;delete this.memoryStore[i];try{"local"===this.type&&this.isBrowser()?window.localStorage.removeItem(i):"cookie"===this.type&&this.isBrowser()&&this.setCookie(i,"",-1)}catch(t){}}getCookie(e){const i=e+"=",t=document.cookie.split(";");for(let a=0;a<t.length;a++){let e=t[a];for(;" "===e.charAt(0);)e=e.substring(1,e.length);if(0===e.indexOf(i))return decodeURIComponent(e.substring(i.length,e.length))}return null}setCookie(e,i,t){let a="";if(t){const e=new Date;e.setTime(e.getTime()+24*t*60*60*1e3),a="; expires="+e.toUTCString()}document.cookie=`${e}=${encodeURIComponent(i)}${a}; path=/; domain=${this.domain}; SameSite=Lax; Secure`}getCookieDomain(){if(!this.isBrowser())return"";const e=window.location.hostname,i=e.split(".");return 1===i.length||"localhost"===e?"":i.length>2?"."+i.slice(-2).join("."):"."+e}isBrowser(){try{return"undefined"!=typeof window&&void 0!==window.document}catch(e){return!1}}isQuotaError(e){return e instanceof DOMException&&(22===e.code||1014===e.code||"QuotaExceededError"===e.name||"NS_ERROR_DOM_QUOTA_REACHED"===e.name)}}class l{constructor(e){i(this,"storage"),i(this,"SESSION_TIMEOUT",18e5),i(this,"deviceId"),i(this,"sessionId"),i(this,"userId",null),i(this,"currentUrl"),i(this,"referrer"),this.storage=new h(e.persistence),this.deviceId=this.getOrSetDeviceId(),this.sessionId="",this.manageSession(),"undefined"!=typeof window?(this.currentUrl=window.location.href,this.referrer=document.referrer,this.listenToHistory()):(this.currentUrl="",this.referrer="")}getOrSetDeviceId(){const e=this.storage.getItem("device_id");if(e)return e;const i=(()=>{if("undefined"==typeof window)return"server-side-id";const e=navigator,i=window.screen,t={userAgent:e.userAgent||"",screenRes:`${i.width}x${i.height}`,colorDepth:i.colorDepth||0,timezone:(new Date).getTimezoneOffset(),language:e.language||"en-US",platform:e.platform||"unknown",hardwareConcurrency:e.hardwareConcurrency||1,deviceMemory:e.deviceMemory||0},a=[t.platform,t.language,t.screenRes,t.colorDepth,t.timezone,t.hardwareConcurrency,t.deviceMemory].join("|");return`${d(a)}-${d(t.userAgent)}`})();return this.storage.setItem("device_id",i),i}manageSession(){const e=Date.now(),i=this.storage.getItem("session_id"),t=parseInt(this.storage.getItem("last_activity")||"0");if(!i||e-t>this.SESSION_TIMEOUT?(this.sessionId=`sess_${e}_${Math.random().toString(36).substr(2,9)}`,this.storage.setItem("session_id",this.sessionId)):this.sessionId=i,this.storage.setItem("last_activity",e.toString()),"undefined"!=typeof window){const e=()=>this.storage.setItem("last_activity",Date.now().toString());window.addEventListener("click",e),window.addEventListener("scroll",e)}}listenToHistory(){const e=history.pushState;history.pushState=(...i)=>{e.apply(history,i),this.handleUrlChange()},window.addEventListener("popstate",()=>this.handleUrlChange())}handleUrlChange(){const e=window.location.href;e!==this.currentUrl&&(this.referrer=this.currentUrl,this.currentUrl=e)}getPayload(){var e;return{library:{name:"@engagepro/analytics",version:"2.0.0"},user:{anonymousId:this.deviceId,id:this.userId},session:{id:this.sessionId,startTime:parseInt(this.sessionId.split("_")[1]||Date.now().toString())},page:{path:"undefined"!=typeof window?window.location.pathname:"",referrer:this.referrer,title:"undefined"!=typeof document?document.title:"",search:"undefined"!=typeof window?window.location.search:"",url:this.currentUrl},network:{online:"undefined"==typeof navigator||navigator.onLine,downlink:null==(e=navigator.connection)?void 0:e.downlink},screen:{width:"undefined"!=typeof screen?screen.width:0,height:"undefined"!=typeof screen?screen.height:0,density:"undefined"!=typeof window?window.devicePixelRatio:1},device:{fingerprint:this.deviceId,type:this.getDeviceType(),userAgent:"undefined"!=typeof navigator?navigator.userAgent:"server"},locale:"undefined"!=typeof navigator?navigator.language:"en-US",timezone:Intl.DateTimeFormat().resolvedOptions().timeZone}}getDeviceType(){if("undefined"==typeof navigator)return"desktop";const e=navigator.userAgent;return/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(e)?"tablet":/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated/.test(e)?"mobile":"desktop"}}class A{constructor(e){i(this,"engageQueue",[]),i(this,"storage"),i(this,"transport"),i(this,"ENGAGE_STORAGE_KEY","engage_events_v2"),i(this,"isFlushing",!1),i(this,"flushInterval"),i(this,"MAX_RETRIES",3),this.transport=e,this.storage=new h("local"),this.load(),"undefined"!=typeof window&&(window.addEventListener("online",()=>{this.flushEngageEvents()}),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&this.flushBeacon()}),window.addEventListener("beforeunload",()=>{this.flushBeacon()})),this.startTimer()}startTimer(){this.flushInterval&&clearInterval(this.flushInterval),this.flushInterval=setInterval(()=>{this.flushEngageEvents()},5e3)}enqueueEngageEvent(e){this.engageQueue.push(e),this.saveEngage(),this.engageQueue.length>=10&&this.flushEngageEvents()}enqueue(e){}saveEngage(){this.storage.setItem(this.ENGAGE_STORAGE_KEY,JSON.stringify(this.engageQueue))}load(){const e=this.storage.getItem(this.ENGAGE_STORAGE_KEY);if(e)try{this.engageQueue=JSON.parse(e)}catch(i){this.engageQueue=[]}}async flushEngageEvents(){if(0===this.engageQueue.length||this.isFlushing)return;if("undefined"!=typeof navigator&&!navigator.onLine)return;this.isFlushing=!0;const e=[...this.engageQueue];this.engageQueue=[],this.saveEngage();let i=0,t=!1;for(;i<this.MAX_RETRIES&&!t;){const a=await this.transport.sendEngageEvents(e);if(a.success){t=!0;break}if(a.permanent)return void(this.isFlushing=!1);if(i++,i<this.MAX_RETRIES){const e=1e3*Math.pow(2,i-1);await new Promise(i=>setTimeout(i,e))}}this.isFlushing=!1}flushBeacon(){if(this.engageQueue.length>0){const e=JSON.stringify({events:this.engageQueue});this.transport.beaconFlush(e)&&(this.engageQueue=[],this.saveEngage())}}}class f{constructor(e){i(this,"apiKey",""),this.endpoints=e}setApiKey(e){this.apiKey=e}async sendEngageEvents(e){const i=JSON.stringify({events:e});return this.sendRaw(i,this.endpoints.engage)}async sendRaw(e,i){const t={"Content-Type":"application/json"};this.apiKey&&(t.Authorization=`Bearer ${this.apiKey}`);try{const a=await fetch(i,{method:"POST",headers:t,body:e,keepalive:!0});return 401===a.status||422===a.status?{success:!1,permanent:!0,status:a.status}:{success:a.ok||202===a.status,permanent:!1,status:a.status}}catch(a){return{success:!1,permanent:!1}}}beaconFlush(e){if("undefined"==typeof navigator||!navigator.sendBeacon)return!1;const i=this.endpoints.engage,t=new Blob([e],{type:"application/json"});return navigator.sendBeacon(i,t)}}const p={"Asia/Kolkata":"IN","Asia/Calcutta":"IN","Asia/Mumbai":"IN","Asia/Dhaka":"BD","Asia/Kathmandu":"NP","Asia/Colombo":"LK","Asia/Karachi":"PK","Asia/Kabul":"AF","Asia/Tehran":"IR","Asia/Dubai":"AE","Asia/Muscat":"OM","Asia/Bahrain":"BH","Asia/Qatar":"QA","Asia/Kuwait":"KW","Asia/Riyadh":"SA","Asia/Aden":"YE","Asia/Baghdad":"IQ","Asia/Amman":"JO","Asia/Beirut":"LB","Asia/Damascus":"SY","Asia/Jerusalem":"IL","Asia/Tel_Aviv":"IL","Asia/Nicosia":"CY","Asia/Tokyo":"JP","Asia/Seoul":"KR","Asia/Pyongyang":"KP","Asia/Shanghai":"CN","Asia/Chongqing":"CN","Asia/Harbin":"CN","Asia/Urumqi":"CN","Asia/Hong_Kong":"HK","Asia/Macau":"MO","Asia/Taipei":"TW","Asia/Singapore":"SG","Asia/Kuala_Lumpur":"MY","Asia/Brunei":"BN","Asia/Jakarta":"ID","Asia/Makassar":"ID","Asia/Jayapura":"ID","Asia/Bangkok":"TH","Asia/Ho_Chi_Minh":"VN","Asia/Saigon":"VN","Asia/Phnom_Penh":"KH","Asia/Vientiane":"LA","Asia/Yangon":"MM","Asia/Rangoon":"MM","Asia/Manila":"PH","Asia/Ulaanbaatar":"MN","Asia/Hovd":"MN","Asia/Tbilisi":"GE","Asia/Baku":"AZ","Asia/Yerevan":"AM","Asia/Almaty":"KZ","Asia/Bishkek":"KG","Asia/Tashkent":"UZ","Asia/Ashgabat":"TM","Asia/Dushanbe":"TJ","Asia/Thimphu":"BT","Asia/Dili":"TL","Europe/London":"GB","Europe/Dublin":"IE","Europe/Lisbon":"PT","Europe/Madrid":"ES","Europe/Paris":"FR","Europe/Brussels":"BE","Europe/Amsterdam":"NL","Europe/Luxembourg":"LU","Europe/Berlin":"DE","Europe/Zurich":"CH","Europe/Vienna":"AT","Europe/Rome":"IT","Europe/Monaco":"MC","Europe/Vatican":"VA","Europe/Malta":"MT","Europe/Prague":"CZ","Europe/Budapest":"HU","Europe/Warsaw":"PL","Europe/Bratislava":"SK","Europe/Ljubljana":"SI","Europe/Zagreb":"HR","Europe/Belgrade":"RS","Europe/Sarajevo":"BA","Europe/Podgorica":"ME","Europe/Skopje":"MK","Europe/Tirane":"AL","Europe/Sofia":"BG","Europe/Bucharest":"RO","Europe/Chisinau":"MD","Europe/Athens":"GR","Europe/Istanbul":"TR","Europe/Helsinki":"FI","Europe/Stockholm":"SE","Europe/Oslo":"NO","Europe/Copenhagen":"DK","Europe/Tallinn":"EE","Europe/Riga":"LV","Europe/Vilnius":"LT","Europe/Minsk":"BY","Europe/Moscow":"RU","Europe/Kaliningrad":"RU","Europe/Samara":"RU","Europe/Kiev":"UA","Europe/Kyiv":"UA","Europe/Reykjavik":"IS","Europe/Andorra":"AD","Europe/Gibraltar":"GI","Europe/San_Marino":"SM","America/New_York":"US","America/Chicago":"US","America/Denver":"US","America/Los_Angeles":"US","America/Phoenix":"US","America/Anchorage":"US","Pacific/Honolulu":"US","America/Detroit":"US","America/Indianapolis":"US","America/Boise":"US","America/Juneau":"US","America/Adak":"US","America/Toronto":"CA","America/Vancouver":"CA","America/Montreal":"CA","America/Winnipeg":"CA","America/Edmonton":"CA","America/Halifax":"CA","America/St_Johns":"CA","America/Regina":"CA","America/Mexico_City":"MX","America/Cancun":"MX","America/Tijuana":"MX","America/Monterrey":"MX","America/Hermosillo":"MX","America/Guatemala":"GT","America/Belize":"BZ","America/El_Salvador":"SV","America/Tegucigalpa":"HN","America/Managua":"NI","America/Costa_Rica":"CR","America/Panama":"PA","America/Bogota":"CO","America/Lima":"PE","America/Guayaquil":"EC","America/Caracas":"VE","America/La_Paz":"BO","America/Asuncion":"PY","America/Montevideo":"UY","America/Buenos_Aires":"AR","America/Argentina/Buenos_Aires":"AR","America/Santiago":"CL","America/Sao_Paulo":"BR","America/Recife":"BR","America/Manaus":"BR","America/Fortaleza":"BR","America/Bahia":"BR","America/Havana":"CU","America/Jamaica":"JM","America/Port-au-Prince":"HT","America/Santo_Domingo":"DO","America/Puerto_Rico":"PR","America/Port_of_Spain":"TT","America/Barbados":"BB","America/Martinique":"MQ","America/Guyana":"GY","America/Paramaribo":"SR","America/Cayenne":"GF","America/Curacao":"CW","Africa/Cairo":"EG","Africa/Casablanca":"MA","Africa/Tunis":"TN","Africa/Algiers":"DZ","Africa/Tripoli":"LY","Africa/Khartoum":"SD","Africa/Addis_Ababa":"ET","Africa/Nairobi":"KE","Africa/Dar_es_Salaam":"TZ","Africa/Kampala":"UG","Africa/Mogadishu":"SO","Africa/Lagos":"NG","Africa/Accra":"GH","Africa/Abidjan":"CI","Africa/Dakar":"SN","Africa/Bamako":"ML","Africa/Ouagadougou":"BF","Africa/Conakry":"GN","Africa/Freetown":"SL","Africa/Monrovia":"LR","Africa/Lome":"TG","Africa/Porto-Novo":"BJ","Africa/Niamey":"NE","Africa/Douala":"CM","Africa/Libreville":"GA","Africa/Bangui":"CF","Africa/Brazzaville":"CG","Africa/Kinshasa":"CD","Africa/Lubumbashi":"CD","Africa/Luanda":"AO","Africa/Maputo":"MZ","Africa/Harare":"ZW","Africa/Lusaka":"ZM","Africa/Lilongwe":"MW","Africa/Johannesburg":"ZA","Africa/Windhoek":"NA","Africa/Gaborone":"BW","Africa/Maseru":"LS","Africa/Mbabane":"SZ","Indian/Antananarivo":"MG","Indian/Mauritius":"MU","Indian/Reunion":"RE","Indian/Comoro":"KM","Indian/Mayotte":"YT","Africa/Djibouti":"DJ","Africa/Asmara":"ER","Australia/Sydney":"AU","Australia/Melbourne":"AU","Australia/Brisbane":"AU","Australia/Perth":"AU","Australia/Adelaide":"AU","Australia/Hobart":"AU","Australia/Darwin":"AU","Australia/Lord_Howe":"AU","Pacific/Auckland":"NZ","Pacific/Chatham":"NZ","Pacific/Fiji":"FJ","Pacific/Tongatapu":"TO","Pacific/Apia":"WS","Pacific/Port_Moresby":"PG","Pacific/Noumea":"NC","Pacific/Guam":"GU","Pacific/Pago_Pago":"AS","Pacific/Tahiti":"PF","Atlantic/Reykjavik":"IS","Atlantic/Azores":"PT","Atlantic/Canary":"ES","Atlantic/Madeira":"PT","Atlantic/Cape_Verde":"CV","Atlantic/Bermuda":"BM","Indian/Maldives":"MV","Indian/Chagos":"IO","Indian/Christmas":"CX","Indian/Cocos":"CC"},m=new Set(["localhost","127.0.0.1"]),g="engage_session_id",y={$:"USD",US$:"USD",USD:"USD","₹":"INR",RS:"INR","RS.":"INR",INR:"INR","€":"EUR",EUR:"EUR","£":"GBP",GBP:"GBP","¥":"JPY",JPY:"JPY"},v=e=>{if("string"!=typeof e)return;const i=e.trim().toUpperCase();return i?y[i]?y[i]:i.includes("₹")||i.startsWith("RS")?"INR":i.includes("$")&&!i.includes("CAD")?"USD":i.includes("€")?"EUR":i.includes("£")?"GBP":i.includes("¥")?"JPY":/^[A-Z]{3}$/.test(i)?i:void 0:void 0};function w(e){if(!e||"object"!=typeof e)return;const i={},t=Object.keys(e).slice(0,20);for(const a of t){const t=e[a];"boolean"==typeof t||"number"==typeof t?i[a]=t:"string"==typeof t&&(i[a]=t.slice(0,100))}return Object.keys(i).length>0?i:void 0}class E{constructor(e){i(this,"config"),i(this,"context"),i(this,"queue"),i(this,"transport"),i(this,"sessionId"),i(this,"countryCode"),i(this,"currentSentiment"),i(this,"identify",(e,i)=>{this.context.userId=e,this.processEvent({event:"Identify",properties:{traits:i},standardEvent:"LOGIN",intent:"identity",confidence:1})}),i(this,"page",(e,i)=>{const t=this.context.getPayload().page;this.processEvent({event:e||t.title||"Unknown Page",properties:{path:t.path,referrer:t.referrer,title:t.title,...i},standardEvent:"PAGE_VIEW",intent:"navigation",confidence:1}),this.emitEngageEvent("pageview",i)}),i(this,"track",(e,i,t)=>{this.processEvent({event:e,properties:i||{},...t});const a={purchase:"purchase",PURCHASE:"purchase",signup:"signup",SIGNUP:"signup",register:"signup",REGISTER:"signup",add_to_cart:"add_to_cart",ADD_TO_CART:"add_to_cart",product_view:"product_view",VIEW_CONTENT:"product_view",session_start:"session_start",session_end:"session_end"},n=a[e]||a[(null==t?void 0:t.standardEvent)||""]||"custom";this.emitEngageEvent(n,i)}),i(this,"trackRevenue",(e,i,t)=>{const a=Math.max(0,(e=>{if("number"==typeof e)return Number.isFinite(e)?e:0;const i=e.trim().replace(/[^0-9.+-]/g,""),t=Number(i);return Number.isFinite(t)?t:0})(e)),n=v(null==i?void 0:i.currency)||v(null==i?void 0:i.currencyCode)||v(null==i?void 0:i.currencySymbol)||("string"==typeof e?v(e):void 0)||"USD";this.track("PURCHASE",{...i||{},value:a,amount:a,valuePaise:Math.round(100*a),amountPaise:Math.round(100*a),currency:n,currencyCode:n},{standardEvent:"PURCHASE",intent:"commerce",confidence:1,...t})}),i(this,"setSentiment",e=>{this.currentSentiment=e}),this.config=e;const t=e.apiKey,a=((e,i,t)=>{if(!e)return t;try{const i=new URL(e);return i.hostname.endsWith("bluenath.com")||m.has(i.hostname)?(i.pathname="/api/v1/analytics/ingest",i.search="",i.hash="",i.toString()):t}catch{return t}})(e.apiHost,0,"https://engage-api.bluenath.com/api/v1/analytics/ingest");this.transport=new f({engage:a}),this.transport.setApiKey(t),this.context=new l({persistence:e.tracking.useCookies?"cookie":"local"}),this.queue=new A(this.transport),this.sessionId=function(){if("undefined"==typeof sessionStorage)return u();let e=sessionStorage.getItem(g);return e||(e=u(),sessionStorage.setItem(g,e)),e}(),this.countryCode=function(){try{const e=Intl.DateTimeFormat().resolvedOptions().timeZone;if(!e)return;return p[e]}catch{return}}(),e.tracking.autoTrack&&"undefined"!=typeof window&&this.page()}emitEngageEvent(e,i){const t=this.context.getPayload().page,a={type:e,timestamp:(new Date).toISOString(),sessionId:this.sessionId,userId:this.context.getPayload().user.id||void 0,countryCode:this.countryCode,sentiment:this.currentSentiment,referrer:(t.referrer||"").slice(0,500),path:t.path||("undefined"!=typeof window?window.location.pathname:"/"),currency:v(null==i?void 0:i.currency)||v(null==i?void 0:i.currencyCode)||void 0,amount:"number"==typeof(null==i?void 0:i.amountPaise)?i.amountPaise:"number"==typeof(null==i?void 0:i.amount)?Math.round(100*i.amount):void 0,productId:"string"==typeof(null==i?void 0:i.productId)?i.productId:void 0,productName:"string"==typeof(null==i?void 0:i.productName)?i.productName:void 0,productCategory:"string"==typeof(null==i?void 0:i.productCategory)?i.productCategory:void 0,metadata:w(null==i?void 0:i.metadata)};this.queue.enqueueEngageEvent(a),this.currentSentiment&&(this.currentSentiment=void 0)}parseRef(e){if(!e)return{};const i=e.match(/^camp_([^_]+)_cr_([^_]+)$/);return i?{campaignId:i[1],creatorId:i[2]}:{}}processEvent(e){const i=this.context.getPayload(),t=e.properties.ref,a=("string"==typeof t?t:void 0)||new URLSearchParams(i.page.search||"").get("ref")||void 0,n=this.parseRef(a),r=e.properties.value??e.properties.amount??e.properties.valuePaise??e.properties.amountPaise,s=Number(r),o=e.properties.campaignId,c=e.properties.creatorId,d=e.properties.currency,h={event:e.event,properties:e.properties,standardEvent:e.standardEvent,intent:e.intent,confidence:e.confidence,rawLabel:e.rawLabel,timestamp:(new Date).toISOString(),messageId:u(),writeKey:this.config.apiKey||"",ref:a,campaignId:("string"==typeof o?o:void 0)||n.campaignId,creatorId:("string"==typeof c?c:void 0)||n.creatorId,value:Number.isFinite(s)?Math.round(s):void 0,valuePaise:Number.isFinite(s)?Math.round(100*s):void 0,currency:("string"==typeof d?d:void 0)||"USD",userId:i.user.id||void 0,anonymousId:i.user.anonymousId,context:i};this.config.debug,this.queue.enqueue(h)}}class S{constructor(e){i(this,"analytics"),i(this,"metrics",{}),this.analytics=e,"undefined"!=typeof window&&"PerformanceObserver"in window&&this.observe()}observe(){try{new PerformanceObserver(e=>{for(const i of e.getEntries()){const e=i;e.hadRecentInput||(this.metrics.cls=(this.metrics.cls||0)+e.value)}}).observe({type:"layout-shift",buffered:!0}),new PerformanceObserver(e=>{const i=e.getEntries(),t=i[i.length-1];this.metrics.lcp=t.renderTime||t.loadTime,this.logMetric("LCP",this.metrics.lcp)}).observe({type:"largest-contentful-paint",buffered:!0}),new PerformanceObserver(e=>{const i=e.getEntries()[0];i&&(this.metrics.fid=i.processingStart-i.startTime,this.logMetric("FID",this.metrics.fid))}).observe({type:"first-input",buffered:!0}),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&this.metrics.cls&&this.logMetric("CLS",this.metrics.cls)})}catch(e){}}logMetric(e,i){i<0||this.analytics.track(`Core Web Vital: ${e}`,{metric:e,value:Math.round(i)},{standardEvent:"PERFORMANCE",intent:"performance",confidence:1,rawLabel:`${e}: ${Math.round(i)}ms`})}}const b=a.createContext(null);let C=null;const R=e=>{if(!C){const i={...e,apiKey:e.apiKey||""};C=new E(i)}return C},M={init:e=>R({apiKey:e.apiKey,apiHost:e.apiHost,tracking:e.tracking||{useCookies:!0,fingerprint:!0,autoTrack:!0},debug:e.debug}),track(e,i){C&&C.track(e,i)},page(e,i){C&&C.page(e,i)},identify(e,i){C&&C.identify(e,i)},trackRevenue(e,i){C&&C.trackRevenue(e,i)},setSentiment(e){C&&C.setSentiment(e)}};exports.EngageProProvider=({children:e,...i})=>{const n=a.useRef(null),r=a.useRef(null);n.current||(n.current=new E(i),"undefined"!=typeof window&&new S(n.current));const s=n.current;return a.useEffect(()=>{if(!i.tracking.autoTrack)return;const e=e=>{const i=e.target.closest('button, a, input[type="submit"], [data-track], .clickable');if(i){const e=Date.now(),t=r.current;t&&t.el===i&&e-t.ts<500?(t.count++,t.ts=e,3===t.count&&(s.track("Rage Click detected",{element:i.tagName},{standardEvent:"RAGE_CLICK",intent:"frustration",confidence:1}),r.current=null)):r.current={el:i,count:1,ts:e};const a=(e=>{let i=(e.innerText||e.value||e.getAttribute("aria-label")||"").trim();if(!i){const t=e.querySelector("img");t&&t.alt&&(i=t.alt);const a=e.querySelector("title");a&&(i=a.textContent||"")}const t=i.slice(0,100),a=t.toLowerCase(),n=(e.id||"").toLowerCase(),r=e.href||"";return/add to (cart|bag)|buy now/.test(a)||n.includes("add-to-cart")?{standard:"ADD_TO_CART",intent:"commerce",label:t,confidence:.9}:/checkout|proceed/.test(a)||r.includes("/checkout")?{standard:"INITIATE_CHECKOUT",intent:"commerce",label:t,confidence:.9}:/place order|pay now/.test(a)||n.includes("place-order")?{standard:"PURCHASE",intent:"commerce",label:t,confidence:.95}:/cancel order/.test(a)||n.includes("cancel")?{standard:"ORDER_CANCEL",intent:"lifecycle",label:t,confidence:.85}:/refund|return/.test(a)||n.includes("refund")?{standard:"ORDER_REFUND",intent:"lifecycle",label:t,confidence:.85}:/track package|shipping/.test(a)?{standard:"TRACK_PACKAGE",intent:"lifecycle",label:t,confidence:.8}:/write review/.test(a)||a.includes("star")&&/^[1-5]/.test(a)?{standard:"RATE_PRODUCT",intent:"engagement",label:t,confidence:.8}:a.includes("search")||n.includes("search")?{standard:"SEARCH",intent:"search",label:t,confidence:.7}:{standard:"GENERIC",intent:"interaction",label:t,confidence:.5}})(i),n="A"===i.tagName;s.track("Interaction",{element:i.tagName.toLowerCase(),id:i.id,destination:n?i.href:void 0},{standardEvent:a.standard,intent:a.intent,rawLabel:a.label,confidence:a.confidence})}},t=e=>{const i=e.target;(e=>"password"===e.getAttribute("type")||"hidden"===e.getAttribute("type")||/password|cvc|card|cc-num|ssn|credit|hidden/i.test(e.getAttribute("name")||e.id||""))(i)||"focusin"!==e.type||i.dataset.tracked||(i.dataset.tracked="true",s.track("Form Start",{field:i.name||i.id},{standardEvent:"FORM_START",intent:"identity"}))},a=()=>{const e=new URLSearchParams(window.location.search);e.has("q")&&s.track("Search Query",{query:e.get("q")},{standardEvent:"SEARCH",intent:"search"}),requestAnimationFrame(()=>s.page())},n=history.pushState;return history.pushState=(...e)=>{n.apply(history,e),a()},window.addEventListener("popstate",a),window.addEventListener("click",e,!0),window.addEventListener("focusin",t,!0),a(),()=>{history.pushState=n,window.removeEventListener("popstate",a),window.removeEventListener("click",e,!0),window.removeEventListener("focusin",t,!0)}},[i.tracking.autoTrack]),t.jsx(b.Provider,{value:s,children:e})},exports.default=E,exports.engage=M,exports.init=R,exports.useAnalytics=()=>{const e=a.useContext(b);if(!e)throw new Error("useAnalytics must be used within EngageProProvider");return e};
|
package/dist/index.js
CHANGED
|
@@ -301,23 +301,19 @@ class Context {
|
|
|
301
301
|
class EventQueue {
|
|
302
302
|
// Spec §3.4
|
|
303
303
|
constructor(transport) {
|
|
304
|
-
__publicField(this, "queue", []);
|
|
305
304
|
__publicField(this, "engageQueue", []);
|
|
306
305
|
__publicField(this, "storage");
|
|
307
306
|
__publicField(this, "transport");
|
|
308
|
-
__publicField(this, "STORAGE_KEY", "engage_queue_v1");
|
|
309
307
|
__publicField(this, "ENGAGE_STORAGE_KEY", "engage_events_v2");
|
|
310
308
|
__publicField(this, "isFlushing", false);
|
|
311
309
|
__publicField(this, "flushInterval");
|
|
312
|
-
__publicField(this, "retryCount", 0);
|
|
313
310
|
__publicField(this, "MAX_RETRIES", 3);
|
|
314
311
|
this.transport = transport;
|
|
315
312
|
this.storage = new StorageEngine("local");
|
|
316
313
|
this.load();
|
|
317
314
|
if (typeof window !== "undefined") {
|
|
318
315
|
window.addEventListener("online", () => {
|
|
319
|
-
this.
|
|
320
|
-
this.flush();
|
|
316
|
+
this.flushEngageEvents();
|
|
321
317
|
});
|
|
322
318
|
window.addEventListener("visibilitychange", () => {
|
|
323
319
|
if (document.visibilityState === "hidden") this.flushBeacon();
|
|
@@ -331,21 +327,12 @@ class EventQueue {
|
|
|
331
327
|
startTimer() {
|
|
332
328
|
if (this.flushInterval) clearInterval(this.flushInterval);
|
|
333
329
|
this.flushInterval = setInterval(() => {
|
|
334
|
-
this.
|
|
330
|
+
this.flushEngageEvents();
|
|
335
331
|
}, 5e3);
|
|
336
332
|
}
|
|
337
333
|
/**
|
|
338
|
-
* Enqueue a
|
|
339
|
-
|
|
340
|
-
enqueue(event) {
|
|
341
|
-
this.queue.push(event);
|
|
342
|
-
this.save();
|
|
343
|
-
if (this.queue.length >= 10 || event.standardEvent === "PURCHASE") {
|
|
344
|
-
this.flush();
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* Enqueue a new EngageEvent (Spec §3.1)
|
|
334
|
+
* Enqueue a new EngageEvent (Spec §3.1).
|
|
335
|
+
* All events go through the authenticated /api/v1/analytics/ingest endpoint.
|
|
349
336
|
*/
|
|
350
337
|
enqueueEngageEvent(event) {
|
|
351
338
|
this.engageQueue.push(event);
|
|
@@ -354,8 +341,12 @@ class EventQueue {
|
|
|
354
341
|
this.flushEngageEvents();
|
|
355
342
|
}
|
|
356
343
|
}
|
|
357
|
-
|
|
358
|
-
|
|
344
|
+
/**
|
|
345
|
+
* Legacy compatibility stub.
|
|
346
|
+
* The old /tracking/ingest endpoint caused 401s with the write key format.
|
|
347
|
+
* Events are already dual-tracked via emitEngageEvent() in Analytics.ts.
|
|
348
|
+
*/
|
|
349
|
+
enqueue(_event) {
|
|
359
350
|
}
|
|
360
351
|
saveEngage() {
|
|
361
352
|
this.storage.setItem(
|
|
@@ -364,56 +355,15 @@ class EventQueue {
|
|
|
364
355
|
);
|
|
365
356
|
}
|
|
366
357
|
load() {
|
|
367
|
-
const data = this.storage.getItem(this.STORAGE_KEY);
|
|
368
|
-
if (data) {
|
|
369
|
-
try {
|
|
370
|
-
this.queue = JSON.parse(data);
|
|
371
|
-
} catch (e) {
|
|
372
|
-
this.queue = [];
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
358
|
const engageData = this.storage.getItem(this.ENGAGE_STORAGE_KEY);
|
|
376
359
|
if (engageData) {
|
|
377
360
|
try {
|
|
378
361
|
this.engageQueue = JSON.parse(engageData);
|
|
379
|
-
} catch (
|
|
362
|
+
} catch (_e) {
|
|
380
363
|
this.engageQueue = [];
|
|
381
364
|
}
|
|
382
365
|
}
|
|
383
366
|
}
|
|
384
|
-
/**
|
|
385
|
-
* Flush legacy events (existing behavior)
|
|
386
|
-
*/
|
|
387
|
-
async flush() {
|
|
388
|
-
if (this.queue.length === 0 || this.isFlushing) {
|
|
389
|
-
if (this.engageQueue.length > 0 && !this.isFlushing) {
|
|
390
|
-
await this.flushEngageEvents();
|
|
391
|
-
}
|
|
392
|
-
return;
|
|
393
|
-
}
|
|
394
|
-
if (typeof navigator !== "undefined" && !navigator.onLine) return;
|
|
395
|
-
this.isFlushing = true;
|
|
396
|
-
const batch = [...this.queue];
|
|
397
|
-
this.queue = [];
|
|
398
|
-
this.save();
|
|
399
|
-
try {
|
|
400
|
-
const success = await this.transport.send(batch);
|
|
401
|
-
if (success) {
|
|
402
|
-
this.retryCount = 0;
|
|
403
|
-
} else {
|
|
404
|
-
throw new Error("Server rejected batch");
|
|
405
|
-
}
|
|
406
|
-
} catch (e) {
|
|
407
|
-
this.queue = [...batch, ...this.queue];
|
|
408
|
-
this.save();
|
|
409
|
-
this.retryCount++;
|
|
410
|
-
} finally {
|
|
411
|
-
this.isFlushing = false;
|
|
412
|
-
}
|
|
413
|
-
if (this.engageQueue.length > 0) {
|
|
414
|
-
await this.flushEngageEvents();
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
367
|
/**
|
|
418
368
|
* Spec §3.4: Flush EngageEvent[] with exponential backoff retry.
|
|
419
369
|
* Max 3 retries with 1s/2s/4s backoff. Drop batch after 3 failures.
|
|
@@ -436,7 +386,7 @@ class EventQueue {
|
|
|
436
386
|
}
|
|
437
387
|
if (result.permanent) {
|
|
438
388
|
console.warn(
|
|
439
|
-
`[EngagePro] Permanent failure (${result.status}). Dropping ${batch.length} events.`
|
|
389
|
+
`[EngagePro] Permanent failure (${result.status}). Dropping ${batch.length} events. Verify your writeKey.`
|
|
440
390
|
);
|
|
441
391
|
this.isFlushing = false;
|
|
442
392
|
return;
|
|
@@ -459,20 +409,9 @@ class EventQueue {
|
|
|
459
409
|
* This is a best-effort fire-and-forget — no retry possible.
|
|
460
410
|
*/
|
|
461
411
|
flushBeacon() {
|
|
462
|
-
if (this.queue.length > 0) {
|
|
463
|
-
const payload = JSON.stringify({
|
|
464
|
-
batch: this.queue,
|
|
465
|
-
sentAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
466
|
-
});
|
|
467
|
-
const sent = this.transport.beaconFlush(payload, "legacy");
|
|
468
|
-
if (sent) {
|
|
469
|
-
this.queue = [];
|
|
470
|
-
this.save();
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
412
|
if (this.engageQueue.length > 0) {
|
|
474
413
|
const payload = JSON.stringify({ events: this.engageQueue });
|
|
475
|
-
const sent = this.transport.beaconFlush(payload
|
|
414
|
+
const sent = this.transport.beaconFlush(payload);
|
|
476
415
|
if (sent) {
|
|
477
416
|
this.engageQueue = [];
|
|
478
417
|
this.saveEngage();
|
|
@@ -489,19 +428,8 @@ class Transport {
|
|
|
489
428
|
this.apiKey = key;
|
|
490
429
|
}
|
|
491
430
|
/**
|
|
492
|
-
* Sends
|
|
493
|
-
*
|
|
494
|
-
*/
|
|
495
|
-
async send(events) {
|
|
496
|
-
const result = await this.sendRaw(
|
|
497
|
-
JSON.stringify({ batch: events, sentAt: (/* @__PURE__ */ new Date()).toISOString() }),
|
|
498
|
-
this.endpoints.legacy
|
|
499
|
-
);
|
|
500
|
-
return result.success;
|
|
501
|
-
}
|
|
502
|
-
/**
|
|
503
|
-
* Sends new EngageEvent[] to the ingest endpoint (Spec §4.1).
|
|
504
|
-
* Returns detailed result for retry logic.
|
|
431
|
+
* Sends EngageEvent[] to the ingest endpoint (Spec §4.1).
|
|
432
|
+
* Uses Bearer auth header. Returns detailed result for retry logic.
|
|
505
433
|
*/
|
|
506
434
|
async sendEngageEvents(events) {
|
|
507
435
|
const payload = JSON.stringify({ events });
|
|
@@ -514,11 +442,6 @@ class Transport {
|
|
|
514
442
|
if (this.apiKey) {
|
|
515
443
|
headers["Authorization"] = `Bearer ${this.apiKey}`;
|
|
516
444
|
}
|
|
517
|
-
if (!this.apiKey && typeof navigator !== "undefined" && navigator.sendBeacon && payload.length < 6e4) {
|
|
518
|
-
const blob = new Blob([payload], { type: "application/json" });
|
|
519
|
-
const success = navigator.sendBeacon(endpoint, blob);
|
|
520
|
-
if (success) return { success: true, permanent: false };
|
|
521
|
-
}
|
|
522
445
|
try {
|
|
523
446
|
const response = await fetch(endpoint, {
|
|
524
447
|
method: "POST",
|
|
@@ -541,12 +464,12 @@ class Transport {
|
|
|
541
464
|
}
|
|
542
465
|
/**
|
|
543
466
|
* Uses sendBeacon for last-resort page unload flush.
|
|
544
|
-
*
|
|
545
|
-
*
|
|
467
|
+
* Note: sendBeacon cannot send custom headers (no Authorization).
|
|
468
|
+
* The ingest endpoint accepts unauthenticated beacon payloads as best-effort.
|
|
546
469
|
*/
|
|
547
|
-
beaconFlush(payload
|
|
470
|
+
beaconFlush(payload) {
|
|
548
471
|
if (typeof navigator === "undefined" || !navigator.sendBeacon) return false;
|
|
549
|
-
const endpoint =
|
|
472
|
+
const endpoint = this.endpoints.engage;
|
|
550
473
|
const blob = new Blob([payload], { type: "application/json" });
|
|
551
474
|
return navigator.sendBeacon(endpoint, blob);
|
|
552
475
|
}
|
|
@@ -808,9 +731,7 @@ function detectCountryFromTimezone() {
|
|
|
808
731
|
return void 0;
|
|
809
732
|
}
|
|
810
733
|
}
|
|
811
|
-
const DEFAULT_INGEST_ENDPOINT = "https://engage-api.bluenath.com/api/v1/tracking/ingest";
|
|
812
734
|
const ENGAGE_INGEST_ENDPOINT = "https://engage-api.bluenath.com/api/v1/analytics/ingest";
|
|
813
|
-
const FIXED_INGEST_PATH = "/api/v1/tracking/ingest";
|
|
814
735
|
const ENGAGE_INGEST_PATH = "/api/v1/analytics/ingest";
|
|
815
736
|
const ALLOWED_DEV_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1"]);
|
|
816
737
|
const DEFAULT_CURRENCY = "USD";
|
|
@@ -985,19 +906,13 @@ class EngagePro {
|
|
|
985
906
|
this.currentSentiment = sentiment;
|
|
986
907
|
});
|
|
987
908
|
this.config = config;
|
|
988
|
-
const apiKey = config.apiKey
|
|
989
|
-
const legacyEndpoint = resolveEndpoint(
|
|
990
|
-
config.apiHost,
|
|
991
|
-
FIXED_INGEST_PATH,
|
|
992
|
-
DEFAULT_INGEST_ENDPOINT
|
|
993
|
-
);
|
|
909
|
+
const apiKey = config.apiKey;
|
|
994
910
|
const engageEndpoint = resolveEndpoint(
|
|
995
911
|
config.apiHost,
|
|
996
912
|
ENGAGE_INGEST_PATH,
|
|
997
913
|
ENGAGE_INGEST_ENDPOINT
|
|
998
914
|
);
|
|
999
915
|
this.transport = new Transport({
|
|
1000
|
-
legacy: legacyEndpoint,
|
|
1001
916
|
engage: engageEndpoint
|
|
1002
917
|
});
|
|
1003
918
|
this.transport.setApiKey(apiKey);
|
|
@@ -1065,7 +980,7 @@ class EngagePro {
|
|
|
1065
980
|
// Metadata
|
|
1066
981
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1067
982
|
messageId: v4(),
|
|
1068
|
-
writeKey: this.config.
|
|
983
|
+
writeKey: this.config.apiKey || "",
|
|
1069
984
|
ref,
|
|
1070
985
|
campaignId: (typeof campaignIdValue === "string" ? campaignIdValue : void 0) || refParts.campaignId,
|
|
1071
986
|
creatorId: (typeof creatorIdValue === "string" ? creatorIdValue : void 0) || refParts.creatorId,
|
|
@@ -1329,8 +1244,7 @@ const init = (config) => {
|
|
|
1329
1244
|
if (!instance) {
|
|
1330
1245
|
const normalizedConfig = {
|
|
1331
1246
|
...config,
|
|
1332
|
-
|
|
1333
|
-
apiKey: config.apiKey || config.writeKey || ""
|
|
1247
|
+
apiKey: config.apiKey || ""
|
|
1334
1248
|
};
|
|
1335
1249
|
instance = new EngagePro(normalizedConfig);
|
|
1336
1250
|
}
|
|
@@ -1339,7 +1253,6 @@ const init = (config) => {
|
|
|
1339
1253
|
const engage = {
|
|
1340
1254
|
init(config) {
|
|
1341
1255
|
return init({
|
|
1342
|
-
writeKey: config.apiKey,
|
|
1343
1256
|
apiKey: config.apiKey,
|
|
1344
1257
|
apiHost: config.apiHost,
|
|
1345
1258
|
tracking: config.tracking || {
|
package/dist/types/index.d.ts
CHANGED
package/package.json
CHANGED