@bluenath/engage 1.0.4 → 2.0.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/README.md +58 -69
- package/dist/core/Analytics.d.ts +5 -3
- package/dist/index.cjs +1 -1
- package/dist/index.js +60 -3
- package/dist/types/index.d.ts +7 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,50 +1,38 @@
|
|
|
1
1
|
# @bluenath/engage
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Production-ready analytics SDK for EngagePro attribution and campaign intelligence.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This SDK captures web events, enriches intent signals, and sends batched payloads to EngagePro ingest for campaign-level ROI measurement.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- 😡 **Rage Click Detection**: Detects user frustration (rapid clicking) automatically.
|
|
9
|
-
- ⚡️ **Performance Monitoring**: Tracks Core Web Vitals (LCP, TTFB, Load Time) out of the box.
|
|
10
|
-
- 🔌 **Offline Support**: Queues events in LocalStorage when offline and syncs when connectivity returns.
|
|
11
|
-
- 🛡️ **PII Protection**: Automatically ignores password and credit card fields.
|
|
12
|
-
- ⚛️ **First-Class React Support**: Drop-in Provider component.
|
|
7
|
+
## Highlights
|
|
13
8
|
|
|
14
|
-
|
|
9
|
+
- Auto-captures high-value interaction events (page, commerce, form, rage-click)
|
|
10
|
+
- Supports manual business events with value and currency fields
|
|
11
|
+
- Handles offline queueing and retry with backoff
|
|
12
|
+
- Includes lightweight React Provider and hook API
|
|
13
|
+
- Protects sensitive input fields during capture
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
npm install @bluenath/engage
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
or
|
|
15
|
+
## Installation
|
|
21
16
|
|
|
22
17
|
```bash
|
|
23
|
-
|
|
18
|
+
npm install @bluenath/engage
|
|
24
19
|
```
|
|
25
20
|
|
|
26
|
-
##
|
|
27
|
-
|
|
28
|
-
### 1. Wrap your App
|
|
21
|
+
## Quick Start (React)
|
|
29
22
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
```jsx
|
|
23
|
+
```tsx
|
|
33
24
|
import React from "react";
|
|
34
25
|
import ReactDOM from "react-dom/client";
|
|
35
26
|
import { EngageProProvider } from "@bluenath/engage";
|
|
36
27
|
import App from "./App";
|
|
37
28
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
root.render(
|
|
29
|
+
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
41
30
|
<EngageProProvider
|
|
42
|
-
writeKey="
|
|
43
|
-
apiHost="https://your-api.com/analyticsdk/ingest"
|
|
31
|
+
writeKey="YOUR_PUBLIC_WRITE_KEY"
|
|
44
32
|
tracking={{
|
|
45
|
-
autoTrack: true,
|
|
46
|
-
useCookies: true,
|
|
47
|
-
fingerprint: true,
|
|
33
|
+
autoTrack: true,
|
|
34
|
+
useCookies: true,
|
|
35
|
+
fingerprint: true,
|
|
48
36
|
}}
|
|
49
37
|
>
|
|
50
38
|
<App />
|
|
@@ -52,59 +40,60 @@ root.render(
|
|
|
52
40
|
);
|
|
53
41
|
```
|
|
54
42
|
|
|
55
|
-
|
|
43
|
+
## Manual Tracking
|
|
56
44
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
```jsx
|
|
45
|
+
```tsx
|
|
60
46
|
import { useAnalytics } from "@bluenath/engage";
|
|
61
47
|
|
|
62
|
-
|
|
63
|
-
const
|
|
48
|
+
export function CheckoutComplete() {
|
|
49
|
+
const analytics = useAnalytics();
|
|
64
50
|
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
51
|
+
const onPurchase = () => {
|
|
52
|
+
analytics.track("PURCHASE", {
|
|
53
|
+
orderId: "ORD-7281",
|
|
54
|
+
amount: 2499,
|
|
55
|
+
currency: "INR",
|
|
56
|
+
ref: "camp_<campaignId>_cr_<creatorId>",
|
|
70
57
|
});
|
|
71
58
|
};
|
|
72
59
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
category: "Tutorial",
|
|
77
|
-
});
|
|
78
|
-
};
|
|
60
|
+
return <button onClick={onPurchase}>Confirm</button>;
|
|
61
|
+
}
|
|
62
|
+
```
|
|
79
63
|
|
|
80
|
-
|
|
81
|
-
|
|
64
|
+
## Attribution Reference Format
|
|
65
|
+
|
|
66
|
+
For campaign-level attribution, include this exact `ref` format in tracked events:
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
camp_<campaignId>_cr_<creatorId>
|
|
82
70
|
```
|
|
83
71
|
|
|
84
|
-
|
|
72
|
+
This allows EngagePro to map conversions to creator partnerships and payout logic.
|
|
73
|
+
|
|
74
|
+
## Endpoint Policy
|
|
75
|
+
|
|
76
|
+
- Production ingest endpoint is fixed to EngagePro managed backend.
|
|
77
|
+
- Optional `apiHost` override is accepted only for local development (`localhost` or `127.0.0.1`).
|
|
78
|
+
- Unsupported hosts are rejected and automatically fall back to the managed endpoint.
|
|
85
79
|
|
|
86
|
-
|
|
80
|
+
## Configuration
|
|
87
81
|
|
|
88
|
-
|
|
|
89
|
-
|
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
| `PERFORMANCE` | Page Load metrics (TTFB, Load Time) |
|
|
82
|
+
| Field | Type | Required | Description |
|
|
83
|
+
| ---------------------- | --------- | -------- | ----------------------------------------------- |
|
|
84
|
+
| `writeKey` | `string` | Yes | Brand public write key from EngagePro dashboard |
|
|
85
|
+
| `apiHost` | `string` | No | Local override only for local development |
|
|
86
|
+
| `tracking.autoTrack` | `boolean` | Yes | Enable DOM interaction capture |
|
|
87
|
+
| `tracking.useCookies` | `boolean` | Yes | Persist anonymous identity across sessions |
|
|
88
|
+
| `tracking.fingerprint` | `boolean` | Yes | Include device fingerprint context |
|
|
89
|
+
| `debug` | `boolean` | No | Log payloads in console for integration testing |
|
|
97
90
|
|
|
98
|
-
##
|
|
91
|
+
## Security Notes
|
|
99
92
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
| `apiHost` | `string` | `...` | The endpoint where events are sent. |
|
|
104
|
-
| `tracking.autoTrack` | `boolean` | `true` | Enables/Disables DOM listening. |
|
|
105
|
-
| `tracking.useCookies` | `boolean` | `false` | Use cookies for cross-subdomain tracking. |
|
|
106
|
-
| `debug` | `boolean` | `false` | Log events to console for debugging. |
|
|
93
|
+
- Do not use internal service keys in frontend apps.
|
|
94
|
+
- Rotate leaked write keys immediately from EngagePro dashboard.
|
|
95
|
+
- Avoid sending raw PII inside custom properties.
|
|
107
96
|
|
|
108
|
-
##
|
|
97
|
+
## License
|
|
109
98
|
|
|
110
|
-
MIT
|
|
99
|
+
MIT
|
package/dist/core/Analytics.d.ts
CHANGED
|
@@ -6,8 +6,10 @@ export declare class EngagePro {
|
|
|
6
6
|
private queue;
|
|
7
7
|
private transport;
|
|
8
8
|
constructor(config: EngageConfig);
|
|
9
|
-
identify: (userId: string, traits?:
|
|
10
|
-
page: (name?: string, properties?:
|
|
11
|
-
track: (eventName: string, properties?:
|
|
9
|
+
identify: (userId: string, traits?: Record<string, unknown>) => void;
|
|
10
|
+
page: (name?: string, properties?: Record<string, unknown>) => void;
|
|
11
|
+
track: (eventName: string, properties?: Record<string, unknown>, intelligence?: Partial<AnalyticsEvent>) => void;
|
|
12
|
+
trackRevenue: (amountPaise: number, properties?: Record<string, unknown>, intelligence?: Partial<AnalyticsEvent>) => void;
|
|
13
|
+
private parseRef;
|
|
12
14
|
private processEvent;
|
|
13
15
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var t=Object.defineProperty,e=(e,n,i)=>((e,n,i)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[n]=i)(e,"symbol"!=typeof n?n+"":n,i);Object.defineProperties(exports,{t:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const n=require("react/jsx-runtime"),i=require("react");let s;const r=new Uint8Array(16);function o(){if(!s&&(s="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!s))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return s(r)}const a=[];for(let g=0;g<256;++g)a.push((g+256).toString(16).slice(1));const c={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function d(t,e,n){if(c.randomUUID&&!t)return c.randomUUID();const i=(t=t||{}).random||(t.rng||o)();return i[6]=15&i[6]|64,i[8]=63&i[8]|128,function(t,e=0){return a[t[e+0]]+a[t[e+1]]+a[t[e+2]]+a[t[e+3]]+"-"+a[t[e+4]]+a[t[e+5]]+"-"+a[t[e+6]]+a[t[e+7]]+"-"+a[t[e+8]]+a[t[e+9]]+"-"+a[t[e+10]]+a[t[e+11]]+a[t[e+12]]+a[t[e+13]]+a[t[e+14]]+a[t[e+15]]}(i)}const h=t=>{let e=2166136261;const n=t.length;for(let i=0;i<n;i++)e^=t.charCodeAt(i),e+=(e<<1)+(e<<4)+(e<<7)+(e<<8)+(e<<24);return("0000000"+(e>>>0).toString(16)).substr(-8)};class l{constructor(t="local"){e(this,"memoryStore",{}),e(this,"keyPrefix","engage_"),e(this,"domain"),this.type=t,this.domain=this.getCookieDomain()}getItem(t){const e=this.keyPrefix+t;if(this.memoryStore.hasOwnProperty(e))return this.memoryStore[e];try{if("local"===this.type&&this.isBrowser())return window.localStorage.getItem(e);if("cookie"===this.type&&this.isBrowser())return this.getCookie(e)}catch(n){return null}return null}setItem(t,e){const n=this.keyPrefix+t;this.memoryStore[n]=e;try{"local"===this.type&&this.isBrowser()?window.localStorage.setItem(n,e):"cookie"===this.type&&this.isBrowser()&&this.setCookie(n,e,365)}catch(i){this.isQuotaError(i)&&(this.type="memory")}}removeItem(t){const e=this.keyPrefix+t;delete this.memoryStore[e];try{"local"===this.type&&this.isBrowser()?window.localStorage.removeItem(e):"cookie"===this.type&&this.isBrowser()&&this.setCookie(e,"",-1)}catch(n){}}getCookie(t){const e=t+"=",n=document.cookie.split(";");for(let i=0;i<n.length;i++){let t=n[i];for(;" "===t.charAt(0);)t=t.substring(1,t.length);if(0===t.indexOf(e))return decodeURIComponent(t.substring(e.length,t.length))}return null}setCookie(t,e,n){let i="";if(n){const t=new Date;t.setTime(t.getTime()+24*n*60*60*1e3),i="; expires="+t.toUTCString()}document.cookie=`${t}=${encodeURIComponent(e)}${i}; path=/; domain=${this.domain}; SameSite=Lax; Secure`}getCookieDomain(){if(!this.isBrowser())return"";const t=window.location.hostname,e=t.split(".");return 1===e.length||"localhost"===t?"":e.length>2?"."+e.slice(-2).join("."):"."+t}isBrowser(){try{return"undefined"!=typeof window&&void 0!==window.document}catch(t){return!1}}isQuotaError(t){return t instanceof DOMException&&(22===t.code||1014===t.code||"QuotaExceededError"===t.name||"NS_ERROR_DOM_QUOTA_REACHED"===t.name)}}class u{constructor(t){e(this,"storage"),e(this,"SESSION_TIMEOUT",18e5),e(this,"deviceId"),e(this,"sessionId"),e(this,"userId",null),e(this,"currentUrl"),e(this,"referrer"),this.storage=new l(t.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 t=this.storage.getItem("device_id");if(t)return t;const e=(()=>{if("undefined"==typeof window)return"server-side-id";const t=navigator,e=window.screen,n={userAgent:t.userAgent||"",screenRes:`${e.width}x${e.height}`,colorDepth:e.colorDepth||0,timezone:(new Date).getTimezoneOffset(),language:t.language||"en-US",platform:t.platform||"unknown",hardwareConcurrency:t.hardwareConcurrency||1,deviceMemory:t.deviceMemory||0},i=[n.platform,n.language,n.screenRes,n.colorDepth,n.timezone,n.hardwareConcurrency,n.deviceMemory].join("|");return`${h(i)}-${h(n.userAgent)}`})();return this.storage.setItem("device_id",e),e}manageSession(){const t=Date.now(),e=this.storage.getItem("session_id"),n=parseInt(this.storage.getItem("last_activity")||"0");if(!e||t-n>this.SESSION_TIMEOUT?(this.sessionId=`sess_${t}_${Math.random().toString(36).substr(2,9)}`,this.storage.setItem("session_id",this.sessionId)):this.sessionId=e,this.storage.setItem("last_activity",t.toString()),"undefined"!=typeof window){const t=()=>this.storage.setItem("last_activity",Date.now().toString());window.addEventListener("click",t),window.addEventListener("scroll",t)}}listenToHistory(){const t=history.pushState;history.pushState=(...e)=>{t.apply(history,e),this.handleUrlChange()},window.addEventListener("popstate",()=>this.handleUrlChange())}handleUrlChange(){const t=window.location.href;t!==this.currentUrl&&(this.referrer=this.currentUrl,this.currentUrl=t)}getPayload(){var t;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==(t=navigator.connection)?void 0:t.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 t=navigator.userAgent;return/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(t)?"tablet":/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated/.test(t)?"mobile":"desktop"}}class f{constructor(t){e(this,"queue",[]),e(this,"storage"),e(this,"transport"),e(this,"STORAGE_KEY","engage_queue_v1"),e(this,"isFlushing",!1),e(this,"flushInterval"),e(this,"retryCount",0),this.transport=t,this.storage=new l("local"),this.load(),"undefined"!=typeof window&&(window.addEventListener("online",()=>{this.retryCount=0,this.flush()}),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&this.flush()})),this.startTimer()}startTimer(){this.flushInterval&&clearInterval(this.flushInterval);const t=3e3*Math.pow(2,this.retryCount);this.flushInterval=setInterval(()=>{this.flush()},Math.min(t,3e4))}enqueue(t){this.queue.push(t),this.save(),(this.queue.length>=10||"PURCHASE"===t.standardEvent)&&this.flush()}save(){this.storage.setItem(this.STORAGE_KEY,JSON.stringify(this.queue))}load(){const t=this.storage.getItem(this.STORAGE_KEY);if(t)try{this.queue=JSON.parse(t)}catch(e){this.queue=[]}}async flush(){if(0===this.queue.length||this.isFlushing)return;if("undefined"!=typeof navigator&&!navigator.onLine)return;this.isFlushing=!0;const t=[...this.queue];this.queue=[],this.save();try{if(!(await this.transport.send(t)))throw new Error("Server rejected batch");this.retryCount=0,this.startTimer()}catch(e){this.queue=[...t,...this.queue],this.save(),this.retryCount++,this.startTimer()}finally{this.isFlushing=!1}}}class w{constructor(t){this.apiEndpoint=t}async send(t){const e=JSON.stringify({batch:t,sentAt:(new Date).toISOString()});if("undefined"!=typeof navigator&&navigator.sendBeacon&&e.length<6e4){const t=new Blob([e],{type:"application/json"});if(navigator.sendBeacon(this.apiEndpoint,t))return!0}try{return(await fetch(this.apiEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:e,keepalive:!0})).ok}catch(n){return!1}}}class p{constructor(t){e(this,"config"),e(this,"context"),e(this,"queue"),e(this,"transport"),e(this,"identify",(t,e)=>{this.context.userId=t,this.processEvent({event:"Identify",properties:{traits:e},standardEvent:"LOGIN",intent:"identity",confidence:1})}),e(this,"page",(t,e)=>{const n=this.context.getPayload().page;this.processEvent({event:t||n.title||"Unknown Page",properties:{path:n.path,referrer:n.referrer,title:n.title,...e},standardEvent:"PAGE_VIEW",intent:"navigation",confidence:1})}),e(this,"track",(t,e,n)=>{this.processEvent({event:t,properties:e||{},...n})}),this.config=t,this.transport=new w(t.apiHost||"http://127.0.0.1:3000/api/v1/tracking/ingest"),this.context=new u({persistence:t.tracking.useCookies?"cookie":"local"}),this.queue=new f(this.transport)}processEvent(t){const e=this.context.getPayload(),n={event:t.event,properties:t.properties,standardEvent:t.standardEvent,intent:t.intent,confidence:t.confidence,rawLabel:t.rawLabel,timestamp:(new Date).toISOString(),messageId:d(),writeKey:this.config.writeKey,userId:e.user.id||void 0,anonymousId:e.user.anonymousId,context:e};this.config.debug,this.queue.enqueue(n)}}class y{constructor(t){e(this,"analytics"),e(this,"metrics",{}),this.analytics=t,"undefined"!=typeof window&&"PerformanceObserver"in window&&this.observe()}observe(){try{new PerformanceObserver(t=>{for(const e of t.getEntries()){const t=e;t.hadRecentInput||(this.metrics.cls=(this.metrics.cls||0)+t.value)}}).observe({type:"layout-shift",buffered:!0}),new PerformanceObserver(t=>{const e=t.getEntries(),n=e[e.length-1];this.metrics.lcp=n.renderTime||n.loadTime,this.logMetric("LCP",this.metrics.lcp)}).observe({type:"largest-contentful-paint",buffered:!0}),new PerformanceObserver(t=>{const e=t.getEntries()[0];e&&(this.metrics.fid=e.processingStart-e.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(t){}}logMetric(t,e){e<0||this.analytics.track(`Core Web Vital: ${t}`,{metric:t,value:Math.round(e)},{standardEvent:"PERFORMANCE",intent:"performance",confidence:1,rawLabel:`${t}: ${Math.round(e)}ms`})}}const v=i.createContext(null);let m=null;exports.EngageProProvider=({children:t,...e})=>{const s=i.useRef(null),r=i.useRef(null);s.current||(s.current=new p(e),"undefined"!=typeof window&&new y(s.current));const o=s.current;return i.useEffect(()=>{if(!e.tracking.autoTrack)return;const t=t=>{const e=t.target.closest('button, a, input[type="submit"], [data-track], .clickable');if(e){const t=Date.now(),n=r.current;n&&n.el===e&&t-n.ts<500?(n.count++,n.ts=t,3===n.count&&(o.track("Rage Click detected",{element:e.tagName},{standardEvent:"RAGE_CLICK",intent:"frustration",confidence:1}),r.current=null)):r.current={el:e,count:1,ts:t};const i=(t=>{let e=(t.innerText||t.value||t.getAttribute("aria-label")||"").trim();if(!e){const n=t.querySelector("img");n&&n.alt&&(e=n.alt);const i=t.querySelector("title");i&&(e=i.textContent||"")}const n=e.slice(0,100),i=n.toLowerCase(),s=(t.id||"").toLowerCase(),r=t.href||"";return/add to (cart|bag)|buy now/.test(i)||s.includes("add-to-cart")?{standard:"ADD_TO_CART",intent:"commerce",label:n,confidence:.9}:/checkout|proceed/.test(i)||r.includes("/checkout")?{standard:"INITIATE_CHECKOUT",intent:"commerce",label:n,confidence:.9}:/place order|pay now/.test(i)||s.includes("place-order")?{standard:"PURCHASE",intent:"commerce",label:n,confidence:.95}:/cancel order/.test(i)||s.includes("cancel")?{standard:"ORDER_CANCEL",intent:"lifecycle",label:n,confidence:.85}:/refund|return/.test(i)||s.includes("refund")?{standard:"ORDER_REFUND",intent:"lifecycle",label:n,confidence:.85}:/track package|shipping/.test(i)?{standard:"TRACK_PACKAGE",intent:"lifecycle",label:n,confidence:.8}:/write review/.test(i)||i.includes("star")&&/^[1-5]/.test(i)?{standard:"RATE_PRODUCT",intent:"engagement",label:n,confidence:.8}:i.includes("search")||s.includes("search")?{standard:"SEARCH",intent:"search",label:n,confidence:.7}:{standard:"GENERIC",intent:"interaction",label:n,confidence:.5}})(e),s="A"===e.tagName;o.track("Interaction",{element:e.tagName.toLowerCase(),id:e.id,destination:s?e.href:void 0},{standardEvent:i.standard,intent:i.intent,rawLabel:i.label,confidence:i.confidence})}},n=t=>{const e=t.target;(t=>"password"===t.getAttribute("type")||"hidden"===t.getAttribute("type")||/password|cvc|card|cc-num|ssn|credit|hidden/i.test(t.getAttribute("name")||t.id||""))(e)||"focusin"!==t.type||e.dataset.tracked||(e.dataset.tracked="true",o.track("Form Start",{field:e.name||e.id},{standardEvent:"FORM_START",intent:"identity"}))},i=()=>{const t=new URLSearchParams(window.location.search);t.has("q")&&o.track("Search Query",{query:t.get("q")},{standardEvent:"SEARCH",intent:"search"}),requestAnimationFrame(()=>o.page())},s=history.pushState;return history.pushState=(...t)=>{s.apply(history,t),i()},window.addEventListener("popstate",i),window.addEventListener("click",t,!0),window.addEventListener("focusin",n,!0),i(),()=>{window.removeEventListener("popstate",i),window.removeEventListener("click",t,!0),window.removeEventListener("focusin",n,!0)}},[e.tracking.autoTrack]),n.jsx(v.Provider,{value:o,children:t})},exports.default=p,exports.init=t=>(m||(m=new p(t)),m),exports.useAnalytics=()=>{const t=i.useContext(v);if(!t)throw new Error("useAnalytics must be used within EngageProProvider");return t};
|
|
1
|
+
"use strict";var t=Object.defineProperty,e=(e,n,i)=>((e,n,i)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[n]=i)(e,"symbol"!=typeof n?n+"":n,i);Object.defineProperties(exports,{t:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const n=require("react/jsx-runtime"),i=require("react");let s;const r=new Uint8Array(16);function o(){if(!s&&(s="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!s))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return s(r)}const a=[];for(let E=0;E<256;++E)a.push((E+256).toString(16).slice(1));const c={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function d(t,e,n){if(c.randomUUID&&!t)return c.randomUUID();const i=(t=t||{}).random||(t.rng||o)();return i[6]=15&i[6]|64,i[8]=63&i[8]|128,function(t,e=0){return a[t[e+0]]+a[t[e+1]]+a[t[e+2]]+a[t[e+3]]+"-"+a[t[e+4]]+a[t[e+5]]+"-"+a[t[e+6]]+a[t[e+7]]+"-"+a[t[e+8]]+a[t[e+9]]+"-"+a[t[e+10]]+a[t[e+11]]+a[t[e+12]]+a[t[e+13]]+a[t[e+14]]+a[t[e+15]]}(i)}const h=t=>{let e=2166136261;const n=t.length;for(let i=0;i<n;i++)e^=t.charCodeAt(i),e+=(e<<1)+(e<<4)+(e<<7)+(e<<8)+(e<<24);return("0000000"+(e>>>0).toString(16)).substr(-8)};class l{constructor(t="local"){e(this,"memoryStore",{}),e(this,"keyPrefix","engage_"),e(this,"domain"),this.type=t,this.domain=this.getCookieDomain()}getItem(t){const e=this.keyPrefix+t;if(this.memoryStore.hasOwnProperty(e))return this.memoryStore[e];try{if("local"===this.type&&this.isBrowser())return window.localStorage.getItem(e);if("cookie"===this.type&&this.isBrowser())return this.getCookie(e)}catch(n){return null}return null}setItem(t,e){const n=this.keyPrefix+t;this.memoryStore[n]=e;try{"local"===this.type&&this.isBrowser()?window.localStorage.setItem(n,e):"cookie"===this.type&&this.isBrowser()&&this.setCookie(n,e,365)}catch(i){this.isQuotaError(i)&&(this.type="memory")}}removeItem(t){const e=this.keyPrefix+t;delete this.memoryStore[e];try{"local"===this.type&&this.isBrowser()?window.localStorage.removeItem(e):"cookie"===this.type&&this.isBrowser()&&this.setCookie(e,"",-1)}catch(n){}}getCookie(t){const e=t+"=",n=document.cookie.split(";");for(let i=0;i<n.length;i++){let t=n[i];for(;" "===t.charAt(0);)t=t.substring(1,t.length);if(0===t.indexOf(e))return decodeURIComponent(t.substring(e.length,t.length))}return null}setCookie(t,e,n){let i="";if(n){const t=new Date;t.setTime(t.getTime()+24*n*60*60*1e3),i="; expires="+t.toUTCString()}document.cookie=`${t}=${encodeURIComponent(e)}${i}; path=/; domain=${this.domain}; SameSite=Lax; Secure`}getCookieDomain(){if(!this.isBrowser())return"";const t=window.location.hostname,e=t.split(".");return 1===e.length||"localhost"===t?"":e.length>2?"."+e.slice(-2).join("."):"."+t}isBrowser(){try{return"undefined"!=typeof window&&void 0!==window.document}catch(t){return!1}}isQuotaError(t){return t instanceof DOMException&&(22===t.code||1014===t.code||"QuotaExceededError"===t.name||"NS_ERROR_DOM_QUOTA_REACHED"===t.name)}}class u{constructor(t){e(this,"storage"),e(this,"SESSION_TIMEOUT",18e5),e(this,"deviceId"),e(this,"sessionId"),e(this,"userId",null),e(this,"currentUrl"),e(this,"referrer"),this.storage=new l(t.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 t=this.storage.getItem("device_id");if(t)return t;const e=(()=>{if("undefined"==typeof window)return"server-side-id";const t=navigator,e=window.screen,n={userAgent:t.userAgent||"",screenRes:`${e.width}x${e.height}`,colorDepth:e.colorDepth||0,timezone:(new Date).getTimezoneOffset(),language:t.language||"en-US",platform:t.platform||"unknown",hardwareConcurrency:t.hardwareConcurrency||1,deviceMemory:t.deviceMemory||0},i=[n.platform,n.language,n.screenRes,n.colorDepth,n.timezone,n.hardwareConcurrency,n.deviceMemory].join("|");return`${h(i)}-${h(n.userAgent)}`})();return this.storage.setItem("device_id",e),e}manageSession(){const t=Date.now(),e=this.storage.getItem("session_id"),n=parseInt(this.storage.getItem("last_activity")||"0");if(!e||t-n>this.SESSION_TIMEOUT?(this.sessionId=`sess_${t}_${Math.random().toString(36).substr(2,9)}`,this.storage.setItem("session_id",this.sessionId)):this.sessionId=e,this.storage.setItem("last_activity",t.toString()),"undefined"!=typeof window){const t=()=>this.storage.setItem("last_activity",Date.now().toString());window.addEventListener("click",t),window.addEventListener("scroll",t)}}listenToHistory(){const t=history.pushState;history.pushState=(...e)=>{t.apply(history,e),this.handleUrlChange()},window.addEventListener("popstate",()=>this.handleUrlChange())}handleUrlChange(){const t=window.location.href;t!==this.currentUrl&&(this.referrer=this.currentUrl,this.currentUrl=t)}getPayload(){var t;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==(t=navigator.connection)?void 0:t.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 t=navigator.userAgent;return/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(t)?"tablet":/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated/.test(t)?"mobile":"desktop"}}class f{constructor(t){e(this,"queue",[]),e(this,"storage"),e(this,"transport"),e(this,"STORAGE_KEY","engage_queue_v1"),e(this,"isFlushing",!1),e(this,"flushInterval"),e(this,"retryCount",0),this.transport=t,this.storage=new l("local"),this.load(),"undefined"!=typeof window&&(window.addEventListener("online",()=>{this.retryCount=0,this.flush()}),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&this.flush()})),this.startTimer()}startTimer(){this.flushInterval&&clearInterval(this.flushInterval);const t=3e3*Math.pow(2,this.retryCount);this.flushInterval=setInterval(()=>{this.flush()},Math.min(t,3e4))}enqueue(t){this.queue.push(t),this.save(),(this.queue.length>=10||"PURCHASE"===t.standardEvent)&&this.flush()}save(){this.storage.setItem(this.STORAGE_KEY,JSON.stringify(this.queue))}load(){const t=this.storage.getItem(this.STORAGE_KEY);if(t)try{this.queue=JSON.parse(t)}catch(e){this.queue=[]}}async flush(){if(0===this.queue.length||this.isFlushing)return;if("undefined"!=typeof navigator&&!navigator.onLine)return;this.isFlushing=!0;const t=[...this.queue];this.queue=[],this.save();try{if(!(await this.transport.send(t)))throw new Error("Server rejected batch");this.retryCount=0,this.startTimer()}catch(e){this.queue=[...t,...this.queue],this.save(),this.retryCount++,this.startTimer()}finally{this.isFlushing=!1}}}class p{constructor(t){this.apiEndpoint=t}async send(t){const e=JSON.stringify({batch:t,sentAt:(new Date).toISOString()});if("undefined"!=typeof navigator&&navigator.sendBeacon&&e.length<6e4){const t=new Blob([e],{type:"application/json"});if(navigator.sendBeacon(this.apiEndpoint,t))return!0}try{return(await fetch(this.apiEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:e,keepalive:!0})).ok}catch(n){return!1}}}const w="https://engage-api.bluenath.com/api/v1/tracking/ingest",y=new Set(["localhost","127.0.0.1"]);class v{constructor(t){e(this,"config"),e(this,"context"),e(this,"queue"),e(this,"transport"),e(this,"identify",(t,e)=>{this.context.userId=t,this.processEvent({event:"Identify",properties:{traits:e},standardEvent:"LOGIN",intent:"identity",confidence:1})}),e(this,"page",(t,e)=>{const n=this.context.getPayload().page;this.processEvent({event:t||n.title||"Unknown Page",properties:{path:n.path,referrer:n.referrer,title:n.title,...e},standardEvent:"PAGE_VIEW",intent:"navigation",confidence:1})}),e(this,"track",(t,e,n)=>{this.processEvent({event:t,properties:e||{},...n})}),e(this,"trackRevenue",(t,e,n)=>{this.track("PURCHASE",{...e||{},value:Math.round(t),valuePaise:Math.round(t)},{standardEvent:"PURCHASE",intent:"commerce",confidence:1,...n})}),this.config=t,this.transport=new p((t=>{if(!t)return w;try{const e=new URL(t);return e.hostname.endsWith("bluenath.com")||y.has(e.hostname)?(e.pathname="/api/v1/tracking/ingest",e.search="",e.hash="",e.toString()):w}catch{return w}})(t.apiHost)),this.context=new u({persistence:t.tracking.useCookies?"cookie":"local"}),this.queue=new f(this.transport)}parseRef(t){if(!t)return{};const e=t.match(/^camp_([^_]+)_cr_([^_]+)$/);return e?{campaignId:e[1],creatorId:e[2]}:{}}processEvent(t){const e=this.context.getPayload(),n=t.properties.ref,i=("string"==typeof n?n:void 0)||new URLSearchParams(e.page.search||"").get("ref")||void 0,s=this.parseRef(i),r=t.properties.valuePaise??t.properties.amountPaise??t.properties.value??t.properties.amount,o=Number(r),a=t.properties.campaignId,c=t.properties.creatorId,h=t.properties.currency,l={event:t.event,properties:t.properties,standardEvent:t.standardEvent,intent:t.intent,confidence:t.confidence,rawLabel:t.rawLabel,timestamp:(new Date).toISOString(),messageId:d(),writeKey:this.config.writeKey,ref:i,campaignId:("string"==typeof a?a:void 0)||s.campaignId,creatorId:("string"==typeof c?c:void 0)||s.creatorId,value:Number.isFinite(o)?Math.round(o):void 0,valuePaise:Number.isFinite(o)?Math.round(o):void 0,currency:("string"==typeof h?h:void 0)||"INR",userId:e.user.id||void 0,anonymousId:e.user.anonymousId,context:e};this.config.debug,this.queue.enqueue(l)}}class m{constructor(t){e(this,"analytics"),e(this,"metrics",{}),this.analytics=t,"undefined"!=typeof window&&"PerformanceObserver"in window&&this.observe()}observe(){try{new PerformanceObserver(t=>{for(const e of t.getEntries()){const t=e;t.hadRecentInput||(this.metrics.cls=(this.metrics.cls||0)+t.value)}}).observe({type:"layout-shift",buffered:!0}),new PerformanceObserver(t=>{const e=t.getEntries(),n=e[e.length-1];this.metrics.lcp=n.renderTime||n.loadTime,this.logMetric("LCP",this.metrics.lcp)}).observe({type:"largest-contentful-paint",buffered:!0}),new PerformanceObserver(t=>{const e=t.getEntries()[0];e&&(this.metrics.fid=e.processingStart-e.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(t){}}logMetric(t,e){e<0||this.analytics.track(`Core Web Vital: ${t}`,{metric:t,value:Math.round(e)},{standardEvent:"PERFORMANCE",intent:"performance",confidence:1,rawLabel:`${t}: ${Math.round(e)}ms`})}}const g=i.createContext(null);let b=null;exports.EngageProProvider=({children:t,...e})=>{const s=i.useRef(null),r=i.useRef(null);s.current||(s.current=new v(e),"undefined"!=typeof window&&new m(s.current));const o=s.current;return i.useEffect(()=>{if(!e.tracking.autoTrack)return;const t=t=>{const e=t.target.closest('button, a, input[type="submit"], [data-track], .clickable');if(e){const t=Date.now(),n=r.current;n&&n.el===e&&t-n.ts<500?(n.count++,n.ts=t,3===n.count&&(o.track("Rage Click detected",{element:e.tagName},{standardEvent:"RAGE_CLICK",intent:"frustration",confidence:1}),r.current=null)):r.current={el:e,count:1,ts:t};const i=(t=>{let e=(t.innerText||t.value||t.getAttribute("aria-label")||"").trim();if(!e){const n=t.querySelector("img");n&&n.alt&&(e=n.alt);const i=t.querySelector("title");i&&(e=i.textContent||"")}const n=e.slice(0,100),i=n.toLowerCase(),s=(t.id||"").toLowerCase(),r=t.href||"";return/add to (cart|bag)|buy now/.test(i)||s.includes("add-to-cart")?{standard:"ADD_TO_CART",intent:"commerce",label:n,confidence:.9}:/checkout|proceed/.test(i)||r.includes("/checkout")?{standard:"INITIATE_CHECKOUT",intent:"commerce",label:n,confidence:.9}:/place order|pay now/.test(i)||s.includes("place-order")?{standard:"PURCHASE",intent:"commerce",label:n,confidence:.95}:/cancel order/.test(i)||s.includes("cancel")?{standard:"ORDER_CANCEL",intent:"lifecycle",label:n,confidence:.85}:/refund|return/.test(i)||s.includes("refund")?{standard:"ORDER_REFUND",intent:"lifecycle",label:n,confidence:.85}:/track package|shipping/.test(i)?{standard:"TRACK_PACKAGE",intent:"lifecycle",label:n,confidence:.8}:/write review/.test(i)||i.includes("star")&&/^[1-5]/.test(i)?{standard:"RATE_PRODUCT",intent:"engagement",label:n,confidence:.8}:i.includes("search")||s.includes("search")?{standard:"SEARCH",intent:"search",label:n,confidence:.7}:{standard:"GENERIC",intent:"interaction",label:n,confidence:.5}})(e),s="A"===e.tagName;o.track("Interaction",{element:e.tagName.toLowerCase(),id:e.id,destination:s?e.href:void 0},{standardEvent:i.standard,intent:i.intent,rawLabel:i.label,confidence:i.confidence})}},n=t=>{const e=t.target;(t=>"password"===t.getAttribute("type")||"hidden"===t.getAttribute("type")||/password|cvc|card|cc-num|ssn|credit|hidden/i.test(t.getAttribute("name")||t.id||""))(e)||"focusin"!==t.type||e.dataset.tracked||(e.dataset.tracked="true",o.track("Form Start",{field:e.name||e.id},{standardEvent:"FORM_START",intent:"identity"}))},i=()=>{const t=new URLSearchParams(window.location.search);t.has("q")&&o.track("Search Query",{query:t.get("q")},{standardEvent:"SEARCH",intent:"search"}),requestAnimationFrame(()=>o.page())},s=history.pushState;return history.pushState=(...t)=>{s.apply(history,t),i()},window.addEventListener("popstate",i),window.addEventListener("click",t,!0),window.addEventListener("focusin",n,!0),i(),()=>{history.pushState=s,window.removeEventListener("popstate",i),window.removeEventListener("click",t,!0),window.removeEventListener("focusin",n,!0)}},[e.tracking.autoTrack]),n.jsx(g.Provider,{value:o,children:t})},exports.default=v,exports.init=t=>(b||(b=new v(t)),b),exports.useAnalytics=()=>{const t=i.useContext(g);if(!t)throw new Error("useAnalytics must be used within EngageProProvider");return t};
|
package/dist/index.js
CHANGED
|
@@ -405,6 +405,28 @@ class Transport {
|
|
|
405
405
|
}
|
|
406
406
|
}
|
|
407
407
|
}
|
|
408
|
+
const DEFAULT_INGEST_ENDPOINT = "https://engage-api.bluenath.com/api/v1/tracking/ingest";
|
|
409
|
+
const FIXED_INGEST_PATH = "/api/v1/tracking/ingest";
|
|
410
|
+
const ALLOWED_DEV_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1"]);
|
|
411
|
+
const resolveIngestEndpoint = (apiHost) => {
|
|
412
|
+
if (!apiHost) return DEFAULT_INGEST_ENDPOINT;
|
|
413
|
+
try {
|
|
414
|
+
const parsed = new URL(apiHost);
|
|
415
|
+
const isAllowedHost = parsed.hostname.endsWith("bluenath.com") || ALLOWED_DEV_HOSTS.has(parsed.hostname);
|
|
416
|
+
if (!isAllowedHost) {
|
|
417
|
+
console.warn(
|
|
418
|
+
`[EngagePro] Ignoring unsupported apiHost "${parsed.hostname}". Falling back to managed endpoint.`
|
|
419
|
+
);
|
|
420
|
+
return DEFAULT_INGEST_ENDPOINT;
|
|
421
|
+
}
|
|
422
|
+
parsed.pathname = FIXED_INGEST_PATH;
|
|
423
|
+
parsed.search = "";
|
|
424
|
+
parsed.hash = "";
|
|
425
|
+
return parsed.toString();
|
|
426
|
+
} catch {
|
|
427
|
+
return DEFAULT_INGEST_ENDPOINT;
|
|
428
|
+
}
|
|
429
|
+
};
|
|
408
430
|
class EngagePro {
|
|
409
431
|
constructor(config) {
|
|
410
432
|
__publicField(this, "config");
|
|
@@ -447,18 +469,46 @@ class EngagePro {
|
|
|
447
469
|
...intelligence
|
|
448
470
|
});
|
|
449
471
|
});
|
|
472
|
+
__publicField(this, "trackRevenue", (amountPaise, properties, intelligence) => {
|
|
473
|
+
this.track(
|
|
474
|
+
"PURCHASE",
|
|
475
|
+
{
|
|
476
|
+
...properties || {},
|
|
477
|
+
value: Math.round(amountPaise),
|
|
478
|
+
valuePaise: Math.round(amountPaise)
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
standardEvent: "PURCHASE",
|
|
482
|
+
intent: "commerce",
|
|
483
|
+
confidence: 1,
|
|
484
|
+
...intelligence
|
|
485
|
+
}
|
|
486
|
+
);
|
|
487
|
+
});
|
|
450
488
|
this.config = config;
|
|
451
|
-
this.transport = new Transport(
|
|
452
|
-
config.apiHost || "http://127.0.0.1:3000/api/v1/tracking/ingest"
|
|
453
|
-
);
|
|
489
|
+
this.transport = new Transport(resolveIngestEndpoint(config.apiHost));
|
|
454
490
|
this.context = new Context({
|
|
455
491
|
persistence: config.tracking.useCookies ? "cookie" : "local"
|
|
456
492
|
});
|
|
457
493
|
this.queue = new EventQueue(this.transport);
|
|
458
494
|
}
|
|
495
|
+
parseRef(ref) {
|
|
496
|
+
if (!ref) return {};
|
|
497
|
+
const m = ref.match(/^camp_([^_]+)_cr_([^_]+)$/);
|
|
498
|
+
if (!m) return {};
|
|
499
|
+
return { campaignId: m[1], creatorId: m[2] };
|
|
500
|
+
}
|
|
459
501
|
// Internal Helper
|
|
460
502
|
processEvent(data) {
|
|
461
503
|
const baseContext = this.context.getPayload();
|
|
504
|
+
const refValue = data.properties.ref;
|
|
505
|
+
const ref = (typeof refValue === "string" ? refValue : void 0) || new URLSearchParams(baseContext.page.search || "").get("ref") || void 0;
|
|
506
|
+
const refParts = this.parseRef(ref);
|
|
507
|
+
const valueCandidate = data.properties.valuePaise ?? data.properties.amountPaise ?? data.properties.value ?? data.properties.amount;
|
|
508
|
+
const value = Number(valueCandidate);
|
|
509
|
+
const campaignIdValue = data.properties.campaignId;
|
|
510
|
+
const creatorIdValue = data.properties.creatorId;
|
|
511
|
+
const currencyValue = data.properties.currency;
|
|
462
512
|
const payload = {
|
|
463
513
|
event: data.event,
|
|
464
514
|
properties: data.properties,
|
|
@@ -471,6 +521,12 @@ class EngagePro {
|
|
|
471
521
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
472
522
|
messageId: v4(),
|
|
473
523
|
writeKey: this.config.writeKey,
|
|
524
|
+
ref,
|
|
525
|
+
campaignId: (typeof campaignIdValue === "string" ? campaignIdValue : void 0) || refParts.campaignId,
|
|
526
|
+
creatorId: (typeof creatorIdValue === "string" ? creatorIdValue : void 0) || refParts.creatorId,
|
|
527
|
+
value: Number.isFinite(value) ? Math.round(value) : void 0,
|
|
528
|
+
valuePaise: Number.isFinite(value) ? Math.round(value) : void 0,
|
|
529
|
+
currency: (typeof currencyValue === "string" ? currencyValue : void 0) || "INR",
|
|
474
530
|
// Identity
|
|
475
531
|
userId: baseContext.user.id || void 0,
|
|
476
532
|
anonymousId: baseContext.user.anonymousId,
|
|
@@ -715,6 +771,7 @@ const EngageProProvider = ({
|
|
|
715
771
|
window.addEventListener("focusin", handleInput, true);
|
|
716
772
|
trackPage();
|
|
717
773
|
return () => {
|
|
774
|
+
history.pushState = originalPush;
|
|
718
775
|
window.removeEventListener("popstate", trackPage);
|
|
719
776
|
window.removeEventListener("click", handleInteraction, true);
|
|
720
777
|
window.removeEventListener("focusin", handleInput, true);
|
package/dist/types/index.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ export interface AnalyticsContext {
|
|
|
39
39
|
}
|
|
40
40
|
export interface AnalyticsEvent {
|
|
41
41
|
event: string;
|
|
42
|
-
properties?: Record<string,
|
|
42
|
+
properties?: Record<string, unknown>;
|
|
43
43
|
standardEvent?: StandardEvent;
|
|
44
44
|
intent?: IntentType;
|
|
45
45
|
confidence?: number;
|
|
@@ -49,6 +49,12 @@ export interface AnalyticsEvent {
|
|
|
49
49
|
timestamp?: string;
|
|
50
50
|
messageId?: string;
|
|
51
51
|
writeKey?: string;
|
|
52
|
+
campaignId?: string;
|
|
53
|
+
creatorId?: string;
|
|
54
|
+
ref?: string;
|
|
55
|
+
value?: number;
|
|
56
|
+
valuePaise?: number;
|
|
57
|
+
currency?: string;
|
|
52
58
|
context?: Partial<AnalyticsContext>;
|
|
53
59
|
}
|
|
54
60
|
export interface EngageConfig {
|