@shware/analytics 2.17.1 → 2.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hooks/use-app-session-analytics.cjs +1 -1
- package/dist/hooks/use-app-session-analytics.cjs.map +1 -1
- package/dist/hooks/use-app-session-analytics.mjs +1 -1
- package/dist/hooks/use-app-session-analytics.mjs.map +1 -1
- package/dist/hooks/use-page-view-analytics.cjs +13 -0
- package/dist/hooks/use-page-view-analytics.cjs.map +1 -1
- package/dist/hooks/use-page-view-analytics.mjs +13 -0
- package/dist/hooks/use-page-view-analytics.mjs.map +1 -1
- package/dist/hooks/use-screen-view-analytics.cjs +8 -0
- package/dist/hooks/use-screen-view-analytics.cjs.map +1 -1
- package/dist/hooks/use-screen-view-analytics.mjs +8 -0
- package/dist/hooks/use-screen-view-analytics.mjs.map +1 -1
- package/dist/hooks/use-web-session-analytics.cjs +1 -1
- package/dist/hooks/use-web-session-analytics.cjs.map +1 -1
- package/dist/hooks/use-web-session-analytics.mjs +1 -1
- package/dist/hooks/use-web-session-analytics.mjs.map +1 -1
- package/dist/third-parties/ignored-events.cjs +33 -25
- package/dist/third-parties/ignored-events.cjs.map +1 -1
- package/dist/third-parties/ignored-events.mjs +33 -25
- package/dist/third-parties/ignored-events.mjs.map +1 -1
- package/dist/track/gtag.cjs.map +1 -1
- package/dist/track/gtag.d.cts +142 -45
- package/dist/track/gtag.d.ts +142 -45
- package/dist/track/gtag.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -48,7 +48,7 @@ function useAppSessionAnalytics() {
|
|
|
48
48
|
(0, import_track.track)("user_engagement", { engagement_time_msec }, { enableThirdPartyTracking: false });
|
|
49
49
|
}, [updateAccumulator]);
|
|
50
50
|
(0, import_react.useEffect)(() => {
|
|
51
|
-
(0, import_track.track)("session_start",
|
|
51
|
+
(0, import_track.track)("session_start", void 0, { enableThirdPartyTracking: false });
|
|
52
52
|
const subscription = import_react_native.AppState.addEventListener("change", (state) => {
|
|
53
53
|
updateAccumulator();
|
|
54
54
|
if (state === "active" && !isActive.current) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/use-app-session-analytics.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { AppState } from 'react-native';\nimport { track } from '../track/index';\n\nexport function useAppSessionAnalytics() {\n const isActive = useRef(true);\n const startTime = useRef(Date.now());\n const accumulatedTime = useRef(0);\n\n const updateAccumulator = useCallback(() => {\n const now = Date.now();\n if (isActive.current) {\n const delta = now - startTime.current;\n if (delta > 0) {\n accumulatedTime.current += delta;\n }\n }\n startTime.current = now;\n }, []);\n\n const sendUserEngagement = useCallback(() => {\n updateAccumulator();\n const engagement_time_msec = accumulatedTime.current;\n accumulatedTime.current = 0;\n if (engagement_time_msec <= 0) return;\n track('user_engagement', { engagement_time_msec }, { enableThirdPartyTracking: false });\n }, [updateAccumulator]);\n\n useEffect(() => {\n track('session_start',
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/use-app-session-analytics.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { AppState } from 'react-native';\nimport { track } from '../track/index';\n\nexport function useAppSessionAnalytics() {\n const isActive = useRef(true);\n const startTime = useRef(Date.now());\n const accumulatedTime = useRef(0);\n\n const updateAccumulator = useCallback(() => {\n const now = Date.now();\n if (isActive.current) {\n const delta = now - startTime.current;\n if (delta > 0) {\n accumulatedTime.current += delta;\n }\n }\n startTime.current = now;\n }, []);\n\n const sendUserEngagement = useCallback(() => {\n updateAccumulator();\n const engagement_time_msec = accumulatedTime.current;\n accumulatedTime.current = 0;\n if (engagement_time_msec <= 0) return;\n track('user_engagement', { engagement_time_msec }, { enableThirdPartyTracking: false });\n }, [updateAccumulator]);\n\n useEffect(() => {\n track('session_start', undefined, { enableThirdPartyTracking: false });\n\n const subscription = AppState.addEventListener('change', (state) => {\n updateAccumulator();\n // when returning to the foreground from the background\n if (state === 'active' && !isActive.current) {\n isActive.current = true;\n }\n // when entering the background\n else if (state !== 'active' && isActive.current) {\n isActive.current = false;\n sendUserEngagement();\n }\n });\n\n return () => subscription.remove();\n }, []);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA+C;AAC/C,0BAAyB;AACzB,mBAAsB;AAEf,SAAS,yBAAyB;AACvC,QAAM,eAAW,qBAAO,IAAI;AAC5B,QAAM,gBAAY,qBAAO,KAAK,IAAI,CAAC;AACnC,QAAM,sBAAkB,qBAAO,CAAC;AAEhC,QAAM,wBAAoB,0BAAY,MAAM;AAC1C,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,SAAS,SAAS;AACpB,YAAM,QAAQ,MAAM,UAAU;AAC9B,UAAI,QAAQ,GAAG;AACb,wBAAgB,WAAW;AAAA,MAC7B;AAAA,IACF;AACA,cAAU,UAAU;AAAA,EACtB,GAAG,CAAC,CAAC;AAEL,QAAM,yBAAqB,0BAAY,MAAM;AAC3C,sBAAkB;AAClB,UAAM,uBAAuB,gBAAgB;AAC7C,oBAAgB,UAAU;AAC1B,QAAI,wBAAwB,EAAG;AAC/B,4BAAM,mBAAmB,EAAE,qBAAqB,GAAG,EAAE,0BAA0B,MAAM,CAAC;AAAA,EACxF,GAAG,CAAC,iBAAiB,CAAC;AAEtB,8BAAU,MAAM;AACd,4BAAM,iBAAiB,QAAW,EAAE,0BAA0B,MAAM,CAAC;AAErE,UAAM,eAAe,6BAAS,iBAAiB,UAAU,CAAC,UAAU;AAClE,wBAAkB;AAElB,UAAI,UAAU,YAAY,CAAC,SAAS,SAAS;AAC3C,iBAAS,UAAU;AAAA,MACrB,WAES,UAAU,YAAY,SAAS,SAAS;AAC/C,iBAAS,UAAU;AACnB,2BAAmB;AAAA,MACrB;AAAA,IACF,CAAC;AAED,WAAO,MAAM,aAAa,OAAO;AAAA,EACnC,GAAG,CAAC,CAAC;AACP;","names":[]}
|
|
@@ -24,7 +24,7 @@ function useAppSessionAnalytics() {
|
|
|
24
24
|
track("user_engagement", { engagement_time_msec }, { enableThirdPartyTracking: false });
|
|
25
25
|
}, [updateAccumulator]);
|
|
26
26
|
useEffect(() => {
|
|
27
|
-
track("session_start",
|
|
27
|
+
track("session_start", void 0, { enableThirdPartyTracking: false });
|
|
28
28
|
const subscription = AppState.addEventListener("change", (state) => {
|
|
29
29
|
updateAccumulator();
|
|
30
30
|
if (state === "active" && !isActive.current) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/use-app-session-analytics.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { AppState } from 'react-native';\nimport { track } from '../track/index';\n\nexport function useAppSessionAnalytics() {\n const isActive = useRef(true);\n const startTime = useRef(Date.now());\n const accumulatedTime = useRef(0);\n\n const updateAccumulator = useCallback(() => {\n const now = Date.now();\n if (isActive.current) {\n const delta = now - startTime.current;\n if (delta > 0) {\n accumulatedTime.current += delta;\n }\n }\n startTime.current = now;\n }, []);\n\n const sendUserEngagement = useCallback(() => {\n updateAccumulator();\n const engagement_time_msec = accumulatedTime.current;\n accumulatedTime.current = 0;\n if (engagement_time_msec <= 0) return;\n track('user_engagement', { engagement_time_msec }, { enableThirdPartyTracking: false });\n }, [updateAccumulator]);\n\n useEffect(() => {\n track('session_start',
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/use-app-session-analytics.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport { AppState } from 'react-native';\nimport { track } from '../track/index';\n\nexport function useAppSessionAnalytics() {\n const isActive = useRef(true);\n const startTime = useRef(Date.now());\n const accumulatedTime = useRef(0);\n\n const updateAccumulator = useCallback(() => {\n const now = Date.now();\n if (isActive.current) {\n const delta = now - startTime.current;\n if (delta > 0) {\n accumulatedTime.current += delta;\n }\n }\n startTime.current = now;\n }, []);\n\n const sendUserEngagement = useCallback(() => {\n updateAccumulator();\n const engagement_time_msec = accumulatedTime.current;\n accumulatedTime.current = 0;\n if (engagement_time_msec <= 0) return;\n track('user_engagement', { engagement_time_msec }, { enableThirdPartyTracking: false });\n }, [updateAccumulator]);\n\n useEffect(() => {\n track('session_start', undefined, { enableThirdPartyTracking: false });\n\n const subscription = AppState.addEventListener('change', (state) => {\n updateAccumulator();\n // when returning to the foreground from the background\n if (state === 'active' && !isActive.current) {\n isActive.current = true;\n }\n // when entering the background\n else if (state !== 'active' && isActive.current) {\n isActive.current = false;\n sendUserEngagement();\n }\n });\n\n return () => subscription.remove();\n }, []);\n}\n"],"mappings":";AAAA,SAAS,aAAa,WAAW,cAAc;AAC/C,SAAS,gBAAgB;AACzB,SAAS,aAAa;AAEf,SAAS,yBAAyB;AACvC,QAAM,WAAW,OAAO,IAAI;AAC5B,QAAM,YAAY,OAAO,KAAK,IAAI,CAAC;AACnC,QAAM,kBAAkB,OAAO,CAAC;AAEhC,QAAM,oBAAoB,YAAY,MAAM;AAC1C,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,SAAS,SAAS;AACpB,YAAM,QAAQ,MAAM,UAAU;AAC9B,UAAI,QAAQ,GAAG;AACb,wBAAgB,WAAW;AAAA,MAC7B;AAAA,IACF;AACA,cAAU,UAAU;AAAA,EACtB,GAAG,CAAC,CAAC;AAEL,QAAM,qBAAqB,YAAY,MAAM;AAC3C,sBAAkB;AAClB,UAAM,uBAAuB,gBAAgB;AAC7C,oBAAgB,UAAU;AAC1B,QAAI,wBAAwB,EAAG;AAC/B,UAAM,mBAAmB,EAAE,qBAAqB,GAAG,EAAE,0BAA0B,MAAM,CAAC;AAAA,EACxF,GAAG,CAAC,iBAAiB,CAAC;AAEtB,YAAU,MAAM;AACd,UAAM,iBAAiB,QAAW,EAAE,0BAA0B,MAAM,CAAC;AAErE,UAAM,eAAe,SAAS,iBAAiB,UAAU,CAAC,UAAU;AAClE,wBAAkB;AAElB,UAAI,UAAU,YAAY,CAAC,SAAS,SAAS;AAC3C,iBAAS,UAAU;AAAA,MACrB,WAES,UAAU,YAAY,SAAS,SAAS;AAC/C,iBAAS,UAAU;AACnB,2BAAmB;AAAA,MACrB;AAAA,IACF,CAAC;AAED,WAAO,MAAM,aAAa,OAAO;AAAA,EACnC,GAAG,CAAC,CAAC;AACP;","names":[]}
|
|
@@ -24,6 +24,7 @@ __export(use_page_view_analytics_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(use_page_view_analytics_exports);
|
|
26
26
|
var import_react = require("react");
|
|
27
|
+
var import_setup = require("../setup/index.cjs");
|
|
27
28
|
var import_track = require("../track/index.cjs");
|
|
28
29
|
var import_use_previous = require("./use-previous.cjs");
|
|
29
30
|
function usePageViewAnalytics(pathname) {
|
|
@@ -42,6 +43,18 @@ function usePageViewAnalytics(pathname) {
|
|
|
42
43
|
document.addEventListener("visibilitychange", handler);
|
|
43
44
|
return () => document.removeEventListener("visibilitychange", handler);
|
|
44
45
|
}, []);
|
|
46
|
+
(0, import_react.useEffect)(() => {
|
|
47
|
+
const key = "first_visit_time";
|
|
48
|
+
if (import_setup.config.storage.getItem(key)) return;
|
|
49
|
+
const properties = {
|
|
50
|
+
page_path: pathname,
|
|
51
|
+
page_title: document.title,
|
|
52
|
+
page_referrer: document.referrer,
|
|
53
|
+
page_location: window.location.href
|
|
54
|
+
};
|
|
55
|
+
(0, import_track.track)("first_visit", properties, { enableThirdPartyTracking: false });
|
|
56
|
+
import_setup.config.storage.setItem(key, (/* @__PURE__ */ new Date()).toISOString());
|
|
57
|
+
}, []);
|
|
45
58
|
(0, import_react.useEffect)(() => {
|
|
46
59
|
if (!prevPathname) {
|
|
47
60
|
session.current = { start: performance.now(), total: 0, isActive: true };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/use-page-view-analytics.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { track } from '../track/index';\nimport { usePrevious } from './use-previous';\n\nexport function usePageViewAnalytics(pathname: string) {\n const prevPathname = usePrevious(pathname);\n const session = useRef({ start: performance.now(), total: 0, isActive: true });\n\n useEffect(() => {\n const handler = () => {\n if (document.hidden) {\n session.current.total += (performance.now() - session.current.start) / 1000;\n session.current.isActive = false;\n } else {\n session.current.start = performance.now();\n session.current.isActive = true;\n }\n };\n document.addEventListener('visibilitychange', handler);\n return () => document.removeEventListener('visibilitychange', handler);\n }, []);\n\n useEffect(() => {\n if (!prevPathname) {\n session.current = { start: performance.now(), total: 0, isActive: true };\n }\n\n let duration = session.current.total;\n if (session.current.isActive) {\n duration += (performance.now() - session.current.start) / 1000;\n }\n\n const properties = {\n page_path: pathname,\n page_title: document.title,\n page_referrer: document.referrer,\n page_location: window.location.href,\n previous_page_path: prevPathname ?? undefined,\n previous_page_path_duration: prevPathname ? Number(duration.toFixed(2)) : undefined,\n };\n\n track('page_view', properties, { enableThirdPartyTracking: false });\n\n // reset session\n session.current = { start: performance.now(), total: 0, isActive: true };\n }, [pathname]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkC;AAClC,mBAAsB;AACtB,0BAA4B;AAErB,SAAS,qBAAqB,UAAkB;AACrD,QAAM,mBAAe,iCAAY,QAAQ;AACzC,QAAM,cAAU,qBAAO,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK,CAAC;AAE7E,8BAAU,MAAM;AACd,UAAM,UAAU,MAAM;AACpB,UAAI,SAAS,QAAQ;AACnB,gBAAQ,QAAQ,UAAU,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AACvE,gBAAQ,QAAQ,WAAW;AAAA,MAC7B,OAAO;AACL,gBAAQ,QAAQ,QAAQ,YAAY,IAAI;AACxC,gBAAQ,QAAQ,WAAW;AAAA,MAC7B;AAAA,IACF;AACA,aAAS,iBAAiB,oBAAoB,OAAO;AACrD,WAAO,MAAM,SAAS,oBAAoB,oBAAoB,OAAO;AAAA,EACvE,GAAG,CAAC,CAAC;AAEL,8BAAU,MAAM;AACd,QAAI,CAAC,cAAc;AACjB,cAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,IACzE;AAEA,QAAI,WAAW,QAAQ,QAAQ;AAC/B,QAAI,QAAQ,QAAQ,UAAU;AAC5B,mBAAa,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AAAA,IAC5D;AAEA,UAAM,aAAa;AAAA,MACjB,WAAW;AAAA,MACX,YAAY,SAAS;AAAA,MACrB,eAAe,SAAS;AAAA,MACxB,eAAe,OAAO,SAAS;AAAA,MAC/B,oBAAoB,gBAAgB;AAAA,MACpC,6BAA6B,eAAe,OAAO,SAAS,QAAQ,CAAC,CAAC,IAAI;AAAA,IAC5E;AAEA,4BAAM,aAAa,YAAY,EAAE,0BAA0B,MAAM,CAAC;AAGlE,YAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,EACzE,GAAG,CAAC,QAAQ,CAAC;AACf;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/use-page-view-analytics.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { config } from '../setup/index';\nimport { track } from '../track/index';\nimport { usePrevious } from './use-previous';\n\nexport function usePageViewAnalytics(pathname: string) {\n const prevPathname = usePrevious(pathname);\n const session = useRef({ start: performance.now(), total: 0, isActive: true });\n\n useEffect(() => {\n const handler = () => {\n if (document.hidden) {\n session.current.total += (performance.now() - session.current.start) / 1000;\n session.current.isActive = false;\n } else {\n session.current.start = performance.now();\n session.current.isActive = true;\n }\n };\n document.addEventListener('visibilitychange', handler);\n return () => document.removeEventListener('visibilitychange', handler);\n }, []);\n\n // send first_visit event when the page is loaded\n useEffect(() => {\n const key = 'first_visit_time';\n if (config.storage.getItem(key)) return;\n const properties = {\n page_path: pathname,\n page_title: document.title,\n page_referrer: document.referrer,\n page_location: window.location.href,\n };\n track('first_visit', properties, { enableThirdPartyTracking: false });\n config.storage.setItem(key, new Date().toISOString());\n }, []);\n\n useEffect(() => {\n if (!prevPathname) {\n session.current = { start: performance.now(), total: 0, isActive: true };\n }\n\n let duration = session.current.total;\n if (session.current.isActive) {\n duration += (performance.now() - session.current.start) / 1000;\n }\n\n const properties = {\n page_path: pathname,\n page_title: document.title,\n page_referrer: document.referrer,\n page_location: window.location.href,\n previous_page_path: prevPathname ?? undefined,\n previous_page_path_duration: prevPathname ? Number(duration.toFixed(2)) : undefined,\n };\n\n track('page_view', properties, { enableThirdPartyTracking: false });\n\n // reset session\n session.current = { start: performance.now(), total: 0, isActive: true };\n }, [pathname]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkC;AAClC,mBAAuB;AACvB,mBAAsB;AACtB,0BAA4B;AAErB,SAAS,qBAAqB,UAAkB;AACrD,QAAM,mBAAe,iCAAY,QAAQ;AACzC,QAAM,cAAU,qBAAO,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK,CAAC;AAE7E,8BAAU,MAAM;AACd,UAAM,UAAU,MAAM;AACpB,UAAI,SAAS,QAAQ;AACnB,gBAAQ,QAAQ,UAAU,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AACvE,gBAAQ,QAAQ,WAAW;AAAA,MAC7B,OAAO;AACL,gBAAQ,QAAQ,QAAQ,YAAY,IAAI;AACxC,gBAAQ,QAAQ,WAAW;AAAA,MAC7B;AAAA,IACF;AACA,aAAS,iBAAiB,oBAAoB,OAAO;AACrD,WAAO,MAAM,SAAS,oBAAoB,oBAAoB,OAAO;AAAA,EACvE,GAAG,CAAC,CAAC;AAGL,8BAAU,MAAM;AACd,UAAM,MAAM;AACZ,QAAI,oBAAO,QAAQ,QAAQ,GAAG,EAAG;AACjC,UAAM,aAAa;AAAA,MACjB,WAAW;AAAA,MACX,YAAY,SAAS;AAAA,MACrB,eAAe,SAAS;AAAA,MACxB,eAAe,OAAO,SAAS;AAAA,IACjC;AACA,4BAAM,eAAe,YAAY,EAAE,0BAA0B,MAAM,CAAC;AACpE,wBAAO,QAAQ,QAAQ,MAAK,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA,EACtD,GAAG,CAAC,CAAC;AAEL,8BAAU,MAAM;AACd,QAAI,CAAC,cAAc;AACjB,cAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,IACzE;AAEA,QAAI,WAAW,QAAQ,QAAQ;AAC/B,QAAI,QAAQ,QAAQ,UAAU;AAC5B,mBAAa,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AAAA,IAC5D;AAEA,UAAM,aAAa;AAAA,MACjB,WAAW;AAAA,MACX,YAAY,SAAS;AAAA,MACrB,eAAe,SAAS;AAAA,MACxB,eAAe,OAAO,SAAS;AAAA,MAC/B,oBAAoB,gBAAgB;AAAA,MACpC,6BAA6B,eAAe,OAAO,SAAS,QAAQ,CAAC,CAAC,IAAI;AAAA,IAC5E;AAEA,4BAAM,aAAa,YAAY,EAAE,0BAA0B,MAAM,CAAC;AAGlE,YAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,EACzE,GAAG,CAAC,QAAQ,CAAC;AACf;","names":[]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/hooks/use-page-view-analytics.ts
|
|
2
2
|
import { useEffect, useRef } from "react";
|
|
3
|
+
import { config } from "../setup/index.mjs";
|
|
3
4
|
import { track } from "../track/index.mjs";
|
|
4
5
|
import { usePrevious } from "./use-previous.mjs";
|
|
5
6
|
function usePageViewAnalytics(pathname) {
|
|
@@ -18,6 +19,18 @@ function usePageViewAnalytics(pathname) {
|
|
|
18
19
|
document.addEventListener("visibilitychange", handler);
|
|
19
20
|
return () => document.removeEventListener("visibilitychange", handler);
|
|
20
21
|
}, []);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const key = "first_visit_time";
|
|
24
|
+
if (config.storage.getItem(key)) return;
|
|
25
|
+
const properties = {
|
|
26
|
+
page_path: pathname,
|
|
27
|
+
page_title: document.title,
|
|
28
|
+
page_referrer: document.referrer,
|
|
29
|
+
page_location: window.location.href
|
|
30
|
+
};
|
|
31
|
+
track("first_visit", properties, { enableThirdPartyTracking: false });
|
|
32
|
+
config.storage.setItem(key, (/* @__PURE__ */ new Date()).toISOString());
|
|
33
|
+
}, []);
|
|
21
34
|
useEffect(() => {
|
|
22
35
|
if (!prevPathname) {
|
|
23
36
|
session.current = { start: performance.now(), total: 0, isActive: true };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/use-page-view-analytics.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { track } from '../track/index';\nimport { usePrevious } from './use-previous';\n\nexport function usePageViewAnalytics(pathname: string) {\n const prevPathname = usePrevious(pathname);\n const session = useRef({ start: performance.now(), total: 0, isActive: true });\n\n useEffect(() => {\n const handler = () => {\n if (document.hidden) {\n session.current.total += (performance.now() - session.current.start) / 1000;\n session.current.isActive = false;\n } else {\n session.current.start = performance.now();\n session.current.isActive = true;\n }\n };\n document.addEventListener('visibilitychange', handler);\n return () => document.removeEventListener('visibilitychange', handler);\n }, []);\n\n useEffect(() => {\n if (!prevPathname) {\n session.current = { start: performance.now(), total: 0, isActive: true };\n }\n\n let duration = session.current.total;\n if (session.current.isActive) {\n duration += (performance.now() - session.current.start) / 1000;\n }\n\n const properties = {\n page_path: pathname,\n page_title: document.title,\n page_referrer: document.referrer,\n page_location: window.location.href,\n previous_page_path: prevPathname ?? undefined,\n previous_page_path_duration: prevPathname ? Number(duration.toFixed(2)) : undefined,\n };\n\n track('page_view', properties, { enableThirdPartyTracking: false });\n\n // reset session\n session.current = { start: performance.now(), total: 0, isActive: true };\n }, [pathname]);\n}\n"],"mappings":";AAAA,SAAS,WAAW,cAAc;AAClC,SAAS,aAAa;AACtB,SAAS,mBAAmB;AAErB,SAAS,qBAAqB,UAAkB;AACrD,QAAM,eAAe,YAAY,QAAQ;AACzC,QAAM,UAAU,OAAO,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK,CAAC;AAE7E,YAAU,MAAM;AACd,UAAM,UAAU,MAAM;AACpB,UAAI,SAAS,QAAQ;AACnB,gBAAQ,QAAQ,UAAU,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AACvE,gBAAQ,QAAQ,WAAW;AAAA,MAC7B,OAAO;AACL,gBAAQ,QAAQ,QAAQ,YAAY,IAAI;AACxC,gBAAQ,QAAQ,WAAW;AAAA,MAC7B;AAAA,IACF;AACA,aAAS,iBAAiB,oBAAoB,OAAO;AACrD,WAAO,MAAM,SAAS,oBAAoB,oBAAoB,OAAO;AAAA,EACvE,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,CAAC,cAAc;AACjB,cAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,IACzE;AAEA,QAAI,WAAW,QAAQ,QAAQ;AAC/B,QAAI,QAAQ,QAAQ,UAAU;AAC5B,mBAAa,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AAAA,IAC5D;AAEA,UAAM,aAAa;AAAA,MACjB,WAAW;AAAA,MACX,YAAY,SAAS;AAAA,MACrB,eAAe,SAAS;AAAA,MACxB,eAAe,OAAO,SAAS;AAAA,MAC/B,oBAAoB,gBAAgB;AAAA,MACpC,6BAA6B,eAAe,OAAO,SAAS,QAAQ,CAAC,CAAC,IAAI;AAAA,IAC5E;AAEA,UAAM,aAAa,YAAY,EAAE,0BAA0B,MAAM,CAAC;AAGlE,YAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,EACzE,GAAG,CAAC,QAAQ,CAAC;AACf;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/use-page-view-analytics.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\nimport { config } from '../setup/index';\nimport { track } from '../track/index';\nimport { usePrevious } from './use-previous';\n\nexport function usePageViewAnalytics(pathname: string) {\n const prevPathname = usePrevious(pathname);\n const session = useRef({ start: performance.now(), total: 0, isActive: true });\n\n useEffect(() => {\n const handler = () => {\n if (document.hidden) {\n session.current.total += (performance.now() - session.current.start) / 1000;\n session.current.isActive = false;\n } else {\n session.current.start = performance.now();\n session.current.isActive = true;\n }\n };\n document.addEventListener('visibilitychange', handler);\n return () => document.removeEventListener('visibilitychange', handler);\n }, []);\n\n // send first_visit event when the page is loaded\n useEffect(() => {\n const key = 'first_visit_time';\n if (config.storage.getItem(key)) return;\n const properties = {\n page_path: pathname,\n page_title: document.title,\n page_referrer: document.referrer,\n page_location: window.location.href,\n };\n track('first_visit', properties, { enableThirdPartyTracking: false });\n config.storage.setItem(key, new Date().toISOString());\n }, []);\n\n useEffect(() => {\n if (!prevPathname) {\n session.current = { start: performance.now(), total: 0, isActive: true };\n }\n\n let duration = session.current.total;\n if (session.current.isActive) {\n duration += (performance.now() - session.current.start) / 1000;\n }\n\n const properties = {\n page_path: pathname,\n page_title: document.title,\n page_referrer: document.referrer,\n page_location: window.location.href,\n previous_page_path: prevPathname ?? undefined,\n previous_page_path_duration: prevPathname ? Number(duration.toFixed(2)) : undefined,\n };\n\n track('page_view', properties, { enableThirdPartyTracking: false });\n\n // reset session\n session.current = { start: performance.now(), total: 0, isActive: true };\n }, [pathname]);\n}\n"],"mappings":";AAAA,SAAS,WAAW,cAAc;AAClC,SAAS,cAAc;AACvB,SAAS,aAAa;AACtB,SAAS,mBAAmB;AAErB,SAAS,qBAAqB,UAAkB;AACrD,QAAM,eAAe,YAAY,QAAQ;AACzC,QAAM,UAAU,OAAO,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK,CAAC;AAE7E,YAAU,MAAM;AACd,UAAM,UAAU,MAAM;AACpB,UAAI,SAAS,QAAQ;AACnB,gBAAQ,QAAQ,UAAU,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AACvE,gBAAQ,QAAQ,WAAW;AAAA,MAC7B,OAAO;AACL,gBAAQ,QAAQ,QAAQ,YAAY,IAAI;AACxC,gBAAQ,QAAQ,WAAW;AAAA,MAC7B;AAAA,IACF;AACA,aAAS,iBAAiB,oBAAoB,OAAO;AACrD,WAAO,MAAM,SAAS,oBAAoB,oBAAoB,OAAO;AAAA,EACvE,GAAG,CAAC,CAAC;AAGL,YAAU,MAAM;AACd,UAAM,MAAM;AACZ,QAAI,OAAO,QAAQ,QAAQ,GAAG,EAAG;AACjC,UAAM,aAAa;AAAA,MACjB,WAAW;AAAA,MACX,YAAY,SAAS;AAAA,MACrB,eAAe,SAAS;AAAA,MACxB,eAAe,OAAO,SAAS;AAAA,IACjC;AACA,UAAM,eAAe,YAAY,EAAE,0BAA0B,MAAM,CAAC;AACpE,WAAO,QAAQ,QAAQ,MAAK,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA,EACtD,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,CAAC,cAAc;AACjB,cAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,IACzE;AAEA,QAAI,WAAW,QAAQ,QAAQ;AAC/B,QAAI,QAAQ,QAAQ,UAAU;AAC5B,mBAAa,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AAAA,IAC5D;AAEA,UAAM,aAAa;AAAA,MACjB,WAAW;AAAA,MACX,YAAY,SAAS;AAAA,MACrB,eAAe,SAAS;AAAA,MACxB,eAAe,OAAO,SAAS;AAAA,MAC/B,oBAAoB,gBAAgB;AAAA,MACpC,6BAA6B,eAAe,OAAO,SAAS,QAAQ,CAAC,CAAC,IAAI;AAAA,IAC5E;AAEA,UAAM,aAAa,YAAY,EAAE,0BAA0B,MAAM,CAAC;AAGlE,YAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,EACzE,GAAG,CAAC,QAAQ,CAAC;AACf;","names":[]}
|
|
@@ -26,6 +26,7 @@ module.exports = __toCommonJS(use_screen_view_analytics_exports);
|
|
|
26
26
|
var import_expo_router = require("expo-router");
|
|
27
27
|
var import_react = require("react");
|
|
28
28
|
var import_react_native = require("react-native");
|
|
29
|
+
var import_setup = require("../setup/index.cjs");
|
|
29
30
|
var import_track = require("../track/index.cjs");
|
|
30
31
|
var import_use_previous = require("./use-previous.cjs");
|
|
31
32
|
function useScreenViewAnalytics() {
|
|
@@ -44,6 +45,13 @@ function useScreenViewAnalytics() {
|
|
|
44
45
|
});
|
|
45
46
|
return () => subscription.remove();
|
|
46
47
|
}, []);
|
|
48
|
+
(0, import_react.useEffect)(() => {
|
|
49
|
+
const key = "first_open_time";
|
|
50
|
+
if (import_setup.config.storage.getItem(key)) return;
|
|
51
|
+
const properties = { screen_name: pathname, screen_class: pathname };
|
|
52
|
+
(0, import_track.track)("first_open", properties, { enableThirdPartyTracking: false });
|
|
53
|
+
import_setup.config.storage.setItem(key, (/* @__PURE__ */ new Date()).toISOString());
|
|
54
|
+
}, []);
|
|
47
55
|
(0, import_react.useEffect)(() => {
|
|
48
56
|
if (!prevPathname) {
|
|
49
57
|
session.current = { start: performance.now(), total: 0, isActive: true };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/use-screen-view-analytics.ts"],"sourcesContent":["import { usePathname } from 'expo-router';\nimport { useEffect, useRef } from 'react';\nimport { AppState } from 'react-native';\nimport { track } from '../track/index';\nimport { usePrevious } from './use-previous';\n\nexport function useScreenViewAnalytics() {\n const pathname = usePathname();\n const prevPathname = usePrevious(pathname);\n const session = useRef({ start: performance.now(), total: 0, isActive: true });\n\n useEffect(() => {\n const subscription = AppState.addEventListener('change', (state) => {\n // when returning to the foreground from the background\n if (state === 'active' && !session.current.isActive) {\n session.current.start = performance.now();\n session.current.isActive = true;\n }\n // when entering the background\n else if (state !== 'active' && session.current.isActive) {\n session.current.total += (performance.now() - session.current.start) / 1000;\n session.current.isActive = false;\n }\n });\n\n return () => subscription.remove();\n }, []);\n\n // when the screen is switched, the duration of the previous screen is recorded\n useEffect(() => {\n if (!prevPathname) {\n session.current = { start: performance.now(), total: 0, isActive: true };\n }\n\n let duration = session.current.total;\n if (session.current.isActive) {\n duration += (performance.now() - session.current.start) / 1000;\n }\n\n track('screen_view', {\n screen_name: pathname,\n screen_class: pathname,\n previous_screen_class: prevPathname ?? undefined,\n previous_screen_class_duration: prevPathname ? Number(duration.toFixed(2)) : undefined,\n });\n\n // reset session\n session.current = { start: performance.now(), total: 0, isActive: true };\n }, [pathname]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAA4B;AAC5B,mBAAkC;AAClC,0BAAyB;AACzB,mBAAsB;AACtB,0BAA4B;AAErB,SAAS,yBAAyB;AACvC,QAAM,eAAW,gCAAY;AAC7B,QAAM,mBAAe,iCAAY,QAAQ;AACzC,QAAM,cAAU,qBAAO,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK,CAAC;AAE7E,8BAAU,MAAM;AACd,UAAM,eAAe,6BAAS,iBAAiB,UAAU,CAAC,UAAU;AAElE,UAAI,UAAU,YAAY,CAAC,QAAQ,QAAQ,UAAU;AACnD,gBAAQ,QAAQ,QAAQ,YAAY,IAAI;AACxC,gBAAQ,QAAQ,WAAW;AAAA,MAC7B,WAES,UAAU,YAAY,QAAQ,QAAQ,UAAU;AACvD,gBAAQ,QAAQ,UAAU,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AACvE,gBAAQ,QAAQ,WAAW;AAAA,MAC7B;AAAA,IACF,CAAC;AAED,WAAO,MAAM,aAAa,OAAO;AAAA,EACnC,GAAG,CAAC,CAAC;AAGL,8BAAU,MAAM;AACd,QAAI,CAAC,cAAc;AACjB,cAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,IACzE;AAEA,QAAI,WAAW,QAAQ,QAAQ;AAC/B,QAAI,QAAQ,QAAQ,UAAU;AAC5B,mBAAa,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AAAA,IAC5D;AAEA,4BAAM,eAAe;AAAA,MACnB,aAAa;AAAA,MACb,cAAc;AAAA,MACd,uBAAuB,gBAAgB;AAAA,MACvC,gCAAgC,eAAe,OAAO,SAAS,QAAQ,CAAC,CAAC,IAAI;AAAA,IAC/E,CAAC;AAGD,YAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,EACzE,GAAG,CAAC,QAAQ,CAAC;AACf;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/use-screen-view-analytics.ts"],"sourcesContent":["import { usePathname } from 'expo-router';\nimport { useEffect, useRef } from 'react';\nimport { AppState } from 'react-native';\nimport { config } from '../setup/index';\nimport { track } from '../track/index';\nimport { usePrevious } from './use-previous';\n\nexport function useScreenViewAnalytics() {\n const pathname = usePathname();\n const prevPathname = usePrevious(pathname);\n const session = useRef({ start: performance.now(), total: 0, isActive: true });\n\n useEffect(() => {\n const subscription = AppState.addEventListener('change', (state) => {\n // when returning to the foreground from the background\n if (state === 'active' && !session.current.isActive) {\n session.current.start = performance.now();\n session.current.isActive = true;\n }\n // when entering the background\n else if (state !== 'active' && session.current.isActive) {\n session.current.total += (performance.now() - session.current.start) / 1000;\n session.current.isActive = false;\n }\n });\n\n return () => subscription.remove();\n }, []);\n\n // send first_visit event when the page is loaded\n useEffect(() => {\n const key = 'first_open_time';\n if (config.storage.getItem(key)) return;\n const properties = { screen_name: pathname, screen_class: pathname };\n track('first_open', properties, { enableThirdPartyTracking: false });\n config.storage.setItem(key, new Date().toISOString());\n }, []);\n\n // when the screen is switched, the duration of the previous screen is recorded\n useEffect(() => {\n if (!prevPathname) {\n session.current = { start: performance.now(), total: 0, isActive: true };\n }\n\n let duration = session.current.total;\n if (session.current.isActive) {\n duration += (performance.now() - session.current.start) / 1000;\n }\n\n track('screen_view', {\n screen_name: pathname,\n screen_class: pathname,\n previous_screen_class: prevPathname ?? undefined,\n previous_screen_class_duration: prevPathname ? Number(duration.toFixed(2)) : undefined,\n });\n\n // reset session\n session.current = { start: performance.now(), total: 0, isActive: true };\n }, [pathname]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAA4B;AAC5B,mBAAkC;AAClC,0BAAyB;AACzB,mBAAuB;AACvB,mBAAsB;AACtB,0BAA4B;AAErB,SAAS,yBAAyB;AACvC,QAAM,eAAW,gCAAY;AAC7B,QAAM,mBAAe,iCAAY,QAAQ;AACzC,QAAM,cAAU,qBAAO,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK,CAAC;AAE7E,8BAAU,MAAM;AACd,UAAM,eAAe,6BAAS,iBAAiB,UAAU,CAAC,UAAU;AAElE,UAAI,UAAU,YAAY,CAAC,QAAQ,QAAQ,UAAU;AACnD,gBAAQ,QAAQ,QAAQ,YAAY,IAAI;AACxC,gBAAQ,QAAQ,WAAW;AAAA,MAC7B,WAES,UAAU,YAAY,QAAQ,QAAQ,UAAU;AACvD,gBAAQ,QAAQ,UAAU,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AACvE,gBAAQ,QAAQ,WAAW;AAAA,MAC7B;AAAA,IACF,CAAC;AAED,WAAO,MAAM,aAAa,OAAO;AAAA,EACnC,GAAG,CAAC,CAAC;AAGL,8BAAU,MAAM;AACd,UAAM,MAAM;AACZ,QAAI,oBAAO,QAAQ,QAAQ,GAAG,EAAG;AACjC,UAAM,aAAa,EAAE,aAAa,UAAU,cAAc,SAAS;AACnE,4BAAM,cAAc,YAAY,EAAE,0BAA0B,MAAM,CAAC;AACnE,wBAAO,QAAQ,QAAQ,MAAK,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA,EACtD,GAAG,CAAC,CAAC;AAGL,8BAAU,MAAM;AACd,QAAI,CAAC,cAAc;AACjB,cAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,IACzE;AAEA,QAAI,WAAW,QAAQ,QAAQ;AAC/B,QAAI,QAAQ,QAAQ,UAAU;AAC5B,mBAAa,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AAAA,IAC5D;AAEA,4BAAM,eAAe;AAAA,MACnB,aAAa;AAAA,MACb,cAAc;AAAA,MACd,uBAAuB,gBAAgB;AAAA,MACvC,gCAAgC,eAAe,OAAO,SAAS,QAAQ,CAAC,CAAC,IAAI;AAAA,IAC/E,CAAC;AAGD,YAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,EACzE,GAAG,CAAC,QAAQ,CAAC;AACf;","names":[]}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { usePathname } from "expo-router";
|
|
3
3
|
import { useEffect, useRef } from "react";
|
|
4
4
|
import { AppState } from "react-native";
|
|
5
|
+
import { config } from "../setup/index.mjs";
|
|
5
6
|
import { track } from "../track/index.mjs";
|
|
6
7
|
import { usePrevious } from "./use-previous.mjs";
|
|
7
8
|
function useScreenViewAnalytics() {
|
|
@@ -20,6 +21,13 @@ function useScreenViewAnalytics() {
|
|
|
20
21
|
});
|
|
21
22
|
return () => subscription.remove();
|
|
22
23
|
}, []);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
const key = "first_open_time";
|
|
26
|
+
if (config.storage.getItem(key)) return;
|
|
27
|
+
const properties = { screen_name: pathname, screen_class: pathname };
|
|
28
|
+
track("first_open", properties, { enableThirdPartyTracking: false });
|
|
29
|
+
config.storage.setItem(key, (/* @__PURE__ */ new Date()).toISOString());
|
|
30
|
+
}, []);
|
|
23
31
|
useEffect(() => {
|
|
24
32
|
if (!prevPathname) {
|
|
25
33
|
session.current = { start: performance.now(), total: 0, isActive: true };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/use-screen-view-analytics.ts"],"sourcesContent":["import { usePathname } from 'expo-router';\nimport { useEffect, useRef } from 'react';\nimport { AppState } from 'react-native';\nimport { track } from '../track/index';\nimport { usePrevious } from './use-previous';\n\nexport function useScreenViewAnalytics() {\n const pathname = usePathname();\n const prevPathname = usePrevious(pathname);\n const session = useRef({ start: performance.now(), total: 0, isActive: true });\n\n useEffect(() => {\n const subscription = AppState.addEventListener('change', (state) => {\n // when returning to the foreground from the background\n if (state === 'active' && !session.current.isActive) {\n session.current.start = performance.now();\n session.current.isActive = true;\n }\n // when entering the background\n else if (state !== 'active' && session.current.isActive) {\n session.current.total += (performance.now() - session.current.start) / 1000;\n session.current.isActive = false;\n }\n });\n\n return () => subscription.remove();\n }, []);\n\n // when the screen is switched, the duration of the previous screen is recorded\n useEffect(() => {\n if (!prevPathname) {\n session.current = { start: performance.now(), total: 0, isActive: true };\n }\n\n let duration = session.current.total;\n if (session.current.isActive) {\n duration += (performance.now() - session.current.start) / 1000;\n }\n\n track('screen_view', {\n screen_name: pathname,\n screen_class: pathname,\n previous_screen_class: prevPathname ?? undefined,\n previous_screen_class_duration: prevPathname ? Number(duration.toFixed(2)) : undefined,\n });\n\n // reset session\n session.current = { start: performance.now(), total: 0, isActive: true };\n }, [pathname]);\n}\n"],"mappings":";AAAA,SAAS,mBAAmB;AAC5B,SAAS,WAAW,cAAc;AAClC,SAAS,gBAAgB;AACzB,SAAS,aAAa;AACtB,SAAS,mBAAmB;AAErB,SAAS,yBAAyB;AACvC,QAAM,WAAW,YAAY;AAC7B,QAAM,eAAe,YAAY,QAAQ;AACzC,QAAM,UAAU,OAAO,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK,CAAC;AAE7E,YAAU,MAAM;AACd,UAAM,eAAe,SAAS,iBAAiB,UAAU,CAAC,UAAU;AAElE,UAAI,UAAU,YAAY,CAAC,QAAQ,QAAQ,UAAU;AACnD,gBAAQ,QAAQ,QAAQ,YAAY,IAAI;AACxC,gBAAQ,QAAQ,WAAW;AAAA,MAC7B,WAES,UAAU,YAAY,QAAQ,QAAQ,UAAU;AACvD,gBAAQ,QAAQ,UAAU,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AACvE,gBAAQ,QAAQ,WAAW;AAAA,MAC7B;AAAA,IACF,CAAC;AAED,WAAO,MAAM,aAAa,OAAO;AAAA,EACnC,GAAG,CAAC,CAAC;AAGL,YAAU,MAAM;AACd,QAAI,CAAC,cAAc;AACjB,cAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,IACzE;AAEA,QAAI,WAAW,QAAQ,QAAQ;AAC/B,QAAI,QAAQ,QAAQ,UAAU;AAC5B,mBAAa,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AAAA,IAC5D;AAEA,UAAM,eAAe;AAAA,MACnB,aAAa;AAAA,MACb,cAAc;AAAA,MACd,uBAAuB,gBAAgB;AAAA,MACvC,gCAAgC,eAAe,OAAO,SAAS,QAAQ,CAAC,CAAC,IAAI;AAAA,IAC/E,CAAC;AAGD,YAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,EACzE,GAAG,CAAC,QAAQ,CAAC;AACf;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/use-screen-view-analytics.ts"],"sourcesContent":["import { usePathname } from 'expo-router';\nimport { useEffect, useRef } from 'react';\nimport { AppState } from 'react-native';\nimport { config } from '../setup/index';\nimport { track } from '../track/index';\nimport { usePrevious } from './use-previous';\n\nexport function useScreenViewAnalytics() {\n const pathname = usePathname();\n const prevPathname = usePrevious(pathname);\n const session = useRef({ start: performance.now(), total: 0, isActive: true });\n\n useEffect(() => {\n const subscription = AppState.addEventListener('change', (state) => {\n // when returning to the foreground from the background\n if (state === 'active' && !session.current.isActive) {\n session.current.start = performance.now();\n session.current.isActive = true;\n }\n // when entering the background\n else if (state !== 'active' && session.current.isActive) {\n session.current.total += (performance.now() - session.current.start) / 1000;\n session.current.isActive = false;\n }\n });\n\n return () => subscription.remove();\n }, []);\n\n // send first_visit event when the page is loaded\n useEffect(() => {\n const key = 'first_open_time';\n if (config.storage.getItem(key)) return;\n const properties = { screen_name: pathname, screen_class: pathname };\n track('first_open', properties, { enableThirdPartyTracking: false });\n config.storage.setItem(key, new Date().toISOString());\n }, []);\n\n // when the screen is switched, the duration of the previous screen is recorded\n useEffect(() => {\n if (!prevPathname) {\n session.current = { start: performance.now(), total: 0, isActive: true };\n }\n\n let duration = session.current.total;\n if (session.current.isActive) {\n duration += (performance.now() - session.current.start) / 1000;\n }\n\n track('screen_view', {\n screen_name: pathname,\n screen_class: pathname,\n previous_screen_class: prevPathname ?? undefined,\n previous_screen_class_duration: prevPathname ? Number(duration.toFixed(2)) : undefined,\n });\n\n // reset session\n session.current = { start: performance.now(), total: 0, isActive: true };\n }, [pathname]);\n}\n"],"mappings":";AAAA,SAAS,mBAAmB;AAC5B,SAAS,WAAW,cAAc;AAClC,SAAS,gBAAgB;AACzB,SAAS,cAAc;AACvB,SAAS,aAAa;AACtB,SAAS,mBAAmB;AAErB,SAAS,yBAAyB;AACvC,QAAM,WAAW,YAAY;AAC7B,QAAM,eAAe,YAAY,QAAQ;AACzC,QAAM,UAAU,OAAO,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK,CAAC;AAE7E,YAAU,MAAM;AACd,UAAM,eAAe,SAAS,iBAAiB,UAAU,CAAC,UAAU;AAElE,UAAI,UAAU,YAAY,CAAC,QAAQ,QAAQ,UAAU;AACnD,gBAAQ,QAAQ,QAAQ,YAAY,IAAI;AACxC,gBAAQ,QAAQ,WAAW;AAAA,MAC7B,WAES,UAAU,YAAY,QAAQ,QAAQ,UAAU;AACvD,gBAAQ,QAAQ,UAAU,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AACvE,gBAAQ,QAAQ,WAAW;AAAA,MAC7B;AAAA,IACF,CAAC;AAED,WAAO,MAAM,aAAa,OAAO;AAAA,EACnC,GAAG,CAAC,CAAC;AAGL,YAAU,MAAM;AACd,UAAM,MAAM;AACZ,QAAI,OAAO,QAAQ,QAAQ,GAAG,EAAG;AACjC,UAAM,aAAa,EAAE,aAAa,UAAU,cAAc,SAAS;AACnE,UAAM,cAAc,YAAY,EAAE,0BAA0B,MAAM,CAAC;AACnE,WAAO,QAAQ,QAAQ,MAAK,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA,EACtD,GAAG,CAAC,CAAC;AAGL,YAAU,MAAM;AACd,QAAI,CAAC,cAAc;AACjB,cAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,IACzE;AAEA,QAAI,WAAW,QAAQ,QAAQ;AAC/B,QAAI,QAAQ,QAAQ,UAAU;AAC5B,mBAAa,YAAY,IAAI,IAAI,QAAQ,QAAQ,SAAS;AAAA,IAC5D;AAEA,UAAM,eAAe;AAAA,MACnB,aAAa;AAAA,MACb,cAAc;AAAA,MACd,uBAAuB,gBAAgB;AAAA,MACvC,gCAAgC,eAAe,OAAO,SAAS,QAAQ,CAAC,CAAC,IAAI;AAAA,IAC/E,CAAC;AAGD,YAAQ,UAAU,EAAE,OAAO,YAAY,IAAI,GAAG,OAAO,GAAG,UAAU,KAAK;AAAA,EACzE,GAAG,CAAC,QAAQ,CAAC;AACf;","names":[]}
|
|
@@ -65,7 +65,7 @@ function useWebSessionAnalytics(pathname) {
|
|
|
65
65
|
isFocused.current = typeof document !== "undefined" && document.hasFocus();
|
|
66
66
|
isVisible.current = typeof document !== "undefined" && document.visibilityState === "visible";
|
|
67
67
|
startTime.current = Date.now();
|
|
68
|
-
(0, import_track.track)("session_start",
|
|
68
|
+
(0, import_track.track)("session_start", void 0, { enableThirdPartyTracking: false });
|
|
69
69
|
const onFocus = () => {
|
|
70
70
|
updateAccumulator();
|
|
71
71
|
isFocused.current = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/use-web-session-analytics.ts"],"sourcesContent":["/**\n * reference:\n * - Discover how long someone spends engaged on your website or app in Google Analytics](https://support.google.com/analytics/answer/11109416?hl=en)\n */\nimport { throttle } from '@shware/utils';\nimport { useCallback, useEffect, useRef } from 'react';\nimport { SESSION_TIMEOUT } from '../setup/session';\nimport { sendBeacon, track } from '../track/index';\n\n/**\n * 1. send session_start event when the page is loaded\n * 2. send scroll event when the user scrolls more than 90% of the page\n * 3. send user_engagement event when the page is hidden or the user is not focused\n */\nexport function useWebSessionAnalytics(pathname: string) {\n const isActive = useRef(true);\n const isFocused = useRef(true);\n const isVisible = useRef(true);\n\n const startTime = useRef(Date.now());\n const accumulatedTime = useRef(0);\n\n const hasSendScroll = useRef(false);\n\n const updateAccumulator = useCallback(() => {\n const now = Date.now();\n if (isFocused.current && isVisible.current && isActive.current) {\n const delta = now - startTime.current;\n if (delta > 0 && delta < SESSION_TIMEOUT) {\n accumulatedTime.current += delta;\n }\n }\n startTime.current = now;\n }, []);\n\n const sendUserEngagement = useCallback(() => {\n updateAccumulator();\n const engagement_time_msec = accumulatedTime.current;\n accumulatedTime.current = 0;\n if (engagement_time_msec <= 0) return;\n sendBeacon('user_engagement', { engagement_time_msec });\n }, [updateAccumulator]);\n\n const sendScroll = useCallback(() => {\n updateAccumulator();\n const engagement_time_msec = accumulatedTime.current;\n accumulatedTime.current = 0;\n if (engagement_time_msec <= 0) return;\n track('scroll', { engagement_time_msec }, { enableThirdPartyTracking: false });\n }, [updateAccumulator]);\n\n // reset scroll state when the pathname changes, so we can send scroll when the user navigates to\n // a new page\n useEffect(() => {\n hasSendScroll.current = false;\n }, [pathname]);\n\n useEffect(() => {\n isFocused.current = typeof document !== 'undefined' && document.hasFocus();\n isVisible.current = typeof document !== 'undefined' && document.visibilityState === 'visible';\n startTime.current = Date.now();\n\n track('session_start',
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/use-web-session-analytics.ts"],"sourcesContent":["/**\n * reference:\n * - Discover how long someone spends engaged on your website or app in Google Analytics](https://support.google.com/analytics/answer/11109416?hl=en)\n */\nimport { throttle } from '@shware/utils';\nimport { useCallback, useEffect, useRef } from 'react';\nimport { SESSION_TIMEOUT } from '../setup/session';\nimport { sendBeacon, track } from '../track/index';\n\n/**\n * 1. send session_start event when the page is loaded\n * 2. send scroll event when the user scrolls more than 90% of the page\n * 3. send user_engagement event when the page is hidden or the user is not focused\n */\nexport function useWebSessionAnalytics(pathname: string) {\n const isActive = useRef(true);\n const isFocused = useRef(true);\n const isVisible = useRef(true);\n\n const startTime = useRef(Date.now());\n const accumulatedTime = useRef(0);\n\n const hasSendScroll = useRef(false);\n\n const updateAccumulator = useCallback(() => {\n const now = Date.now();\n if (isFocused.current && isVisible.current && isActive.current) {\n const delta = now - startTime.current;\n if (delta > 0 && delta < SESSION_TIMEOUT) {\n accumulatedTime.current += delta;\n }\n }\n startTime.current = now;\n }, []);\n\n const sendUserEngagement = useCallback(() => {\n updateAccumulator();\n const engagement_time_msec = accumulatedTime.current;\n accumulatedTime.current = 0;\n if (engagement_time_msec <= 0) return;\n sendBeacon('user_engagement', { engagement_time_msec });\n }, [updateAccumulator]);\n\n const sendScroll = useCallback(() => {\n updateAccumulator();\n const engagement_time_msec = accumulatedTime.current;\n accumulatedTime.current = 0;\n if (engagement_time_msec <= 0) return;\n track('scroll', { engagement_time_msec }, { enableThirdPartyTracking: false });\n }, [updateAccumulator]);\n\n // reset scroll state when the pathname changes, so we can send scroll when the user navigates to\n // a new page\n useEffect(() => {\n hasSendScroll.current = false;\n }, [pathname]);\n\n useEffect(() => {\n isFocused.current = typeof document !== 'undefined' && document.hasFocus();\n isVisible.current = typeof document !== 'undefined' && document.visibilityState === 'visible';\n startTime.current = Date.now();\n\n track('session_start', undefined, { enableThirdPartyTracking: false });\n\n const onFocus = () => {\n updateAccumulator();\n isFocused.current = true;\n };\n\n const onBlur = () => {\n updateAccumulator();\n isFocused.current = false;\n };\n\n const onPageShow = () => {\n updateAccumulator();\n isActive.current = true;\n };\n\n const onPageHide = () => {\n updateAccumulator();\n isActive.current = false;\n sendUserEngagement();\n };\n\n const onVisibilityChange = () => {\n updateAccumulator();\n if (document.visibilityState === 'visible') {\n isVisible.current = true;\n } else {\n isVisible.current = false;\n sendUserEngagement();\n }\n };\n\n const onScroll = throttle(() => {\n updateAccumulator();\n if (hasSendScroll.current) return;\n\n // only send scroll when the user has scrolled more than 90% of the page\n const scrollTop = window.scrollY || document.documentElement.scrollTop;\n const windowHeight = window.innerHeight;\n const docHeight = document.documentElement.scrollHeight;\n if (docHeight === 0) return;\n const scrollPercent = (scrollTop + windowHeight) / docHeight;\n if (scrollPercent < 0.9) return;\n hasSendScroll.current = true;\n\n sendScroll();\n }, 500);\n\n const checkpointEvents = ['mousedown', 'keydown', 'touchstart'];\n const checkpoint = throttle(updateAccumulator, 1000);\n\n window.addEventListener('focus', onFocus, { passive: true });\n window.addEventListener('blur', onBlur, { passive: true });\n window.addEventListener('pageshow', onPageShow, { passive: true });\n window.addEventListener('pagehide', onPageHide, { passive: true });\n window.addEventListener('scroll', onScroll, { passive: true });\n document.addEventListener('visibilitychange', onVisibilityChange, { passive: true });\n\n // save checkpoint\n checkpointEvents.forEach((event) => {\n window.addEventListener(event, checkpoint, { passive: true, capture: true });\n });\n\n return () => {\n window.removeEventListener('focus', onFocus);\n window.removeEventListener('blur', onBlur);\n window.removeEventListener('pageshow', onPageShow);\n window.removeEventListener('pagehide', onPageHide);\n window.removeEventListener('scroll', onScroll);\n document.removeEventListener('visibilitychange', onVisibilityChange);\n\n checkpointEvents.forEach((event) => {\n window.removeEventListener(event, checkpoint);\n });\n\n onScroll.cancel();\n checkpoint.cancel();\n };\n }, []);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -41,7 +41,7 @@ function useWebSessionAnalytics(pathname) {
|
|
|
41
41
|
isFocused.current = typeof document !== "undefined" && document.hasFocus();
|
|
42
42
|
isVisible.current = typeof document !== "undefined" && document.visibilityState === "visible";
|
|
43
43
|
startTime.current = Date.now();
|
|
44
|
-
track("session_start",
|
|
44
|
+
track("session_start", void 0, { enableThirdPartyTracking: false });
|
|
45
45
|
const onFocus = () => {
|
|
46
46
|
updateAccumulator();
|
|
47
47
|
isFocused.current = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/use-web-session-analytics.ts"],"sourcesContent":["/**\n * reference:\n * - Discover how long someone spends engaged on your website or app in Google Analytics](https://support.google.com/analytics/answer/11109416?hl=en)\n */\nimport { throttle } from '@shware/utils';\nimport { useCallback, useEffect, useRef } from 'react';\nimport { SESSION_TIMEOUT } from '../setup/session';\nimport { sendBeacon, track } from '../track/index';\n\n/**\n * 1. send session_start event when the page is loaded\n * 2. send scroll event when the user scrolls more than 90% of the page\n * 3. send user_engagement event when the page is hidden or the user is not focused\n */\nexport function useWebSessionAnalytics(pathname: string) {\n const isActive = useRef(true);\n const isFocused = useRef(true);\n const isVisible = useRef(true);\n\n const startTime = useRef(Date.now());\n const accumulatedTime = useRef(0);\n\n const hasSendScroll = useRef(false);\n\n const updateAccumulator = useCallback(() => {\n const now = Date.now();\n if (isFocused.current && isVisible.current && isActive.current) {\n const delta = now - startTime.current;\n if (delta > 0 && delta < SESSION_TIMEOUT) {\n accumulatedTime.current += delta;\n }\n }\n startTime.current = now;\n }, []);\n\n const sendUserEngagement = useCallback(() => {\n updateAccumulator();\n const engagement_time_msec = accumulatedTime.current;\n accumulatedTime.current = 0;\n if (engagement_time_msec <= 0) return;\n sendBeacon('user_engagement', { engagement_time_msec });\n }, [updateAccumulator]);\n\n const sendScroll = useCallback(() => {\n updateAccumulator();\n const engagement_time_msec = accumulatedTime.current;\n accumulatedTime.current = 0;\n if (engagement_time_msec <= 0) return;\n track('scroll', { engagement_time_msec }, { enableThirdPartyTracking: false });\n }, [updateAccumulator]);\n\n // reset scroll state when the pathname changes, so we can send scroll when the user navigates to\n // a new page\n useEffect(() => {\n hasSendScroll.current = false;\n }, [pathname]);\n\n useEffect(() => {\n isFocused.current = typeof document !== 'undefined' && document.hasFocus();\n isVisible.current = typeof document !== 'undefined' && document.visibilityState === 'visible';\n startTime.current = Date.now();\n\n track('session_start',
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/use-web-session-analytics.ts"],"sourcesContent":["/**\n * reference:\n * - Discover how long someone spends engaged on your website or app in Google Analytics](https://support.google.com/analytics/answer/11109416?hl=en)\n */\nimport { throttle } from '@shware/utils';\nimport { useCallback, useEffect, useRef } from 'react';\nimport { SESSION_TIMEOUT } from '../setup/session';\nimport { sendBeacon, track } from '../track/index';\n\n/**\n * 1. send session_start event when the page is loaded\n * 2. send scroll event when the user scrolls more than 90% of the page\n * 3. send user_engagement event when the page is hidden or the user is not focused\n */\nexport function useWebSessionAnalytics(pathname: string) {\n const isActive = useRef(true);\n const isFocused = useRef(true);\n const isVisible = useRef(true);\n\n const startTime = useRef(Date.now());\n const accumulatedTime = useRef(0);\n\n const hasSendScroll = useRef(false);\n\n const updateAccumulator = useCallback(() => {\n const now = Date.now();\n if (isFocused.current && isVisible.current && isActive.current) {\n const delta = now - startTime.current;\n if (delta > 0 && delta < SESSION_TIMEOUT) {\n accumulatedTime.current += delta;\n }\n }\n startTime.current = now;\n }, []);\n\n const sendUserEngagement = useCallback(() => {\n updateAccumulator();\n const engagement_time_msec = accumulatedTime.current;\n accumulatedTime.current = 0;\n if (engagement_time_msec <= 0) return;\n sendBeacon('user_engagement', { engagement_time_msec });\n }, [updateAccumulator]);\n\n const sendScroll = useCallback(() => {\n updateAccumulator();\n const engagement_time_msec = accumulatedTime.current;\n accumulatedTime.current = 0;\n if (engagement_time_msec <= 0) return;\n track('scroll', { engagement_time_msec }, { enableThirdPartyTracking: false });\n }, [updateAccumulator]);\n\n // reset scroll state when the pathname changes, so we can send scroll when the user navigates to\n // a new page\n useEffect(() => {\n hasSendScroll.current = false;\n }, [pathname]);\n\n useEffect(() => {\n isFocused.current = typeof document !== 'undefined' && document.hasFocus();\n isVisible.current = typeof document !== 'undefined' && document.visibilityState === 'visible';\n startTime.current = Date.now();\n\n track('session_start', undefined, { enableThirdPartyTracking: false });\n\n const onFocus = () => {\n updateAccumulator();\n isFocused.current = true;\n };\n\n const onBlur = () => {\n updateAccumulator();\n isFocused.current = false;\n };\n\n const onPageShow = () => {\n updateAccumulator();\n isActive.current = true;\n };\n\n const onPageHide = () => {\n updateAccumulator();\n isActive.current = false;\n sendUserEngagement();\n };\n\n const onVisibilityChange = () => {\n updateAccumulator();\n if (document.visibilityState === 'visible') {\n isVisible.current = true;\n } else {\n isVisible.current = false;\n sendUserEngagement();\n }\n };\n\n const onScroll = throttle(() => {\n updateAccumulator();\n if (hasSendScroll.current) return;\n\n // only send scroll when the user has scrolled more than 90% of the page\n const scrollTop = window.scrollY || document.documentElement.scrollTop;\n const windowHeight = window.innerHeight;\n const docHeight = document.documentElement.scrollHeight;\n if (docHeight === 0) return;\n const scrollPercent = (scrollTop + windowHeight) / docHeight;\n if (scrollPercent < 0.9) return;\n hasSendScroll.current = true;\n\n sendScroll();\n }, 500);\n\n const checkpointEvents = ['mousedown', 'keydown', 'touchstart'];\n const checkpoint = throttle(updateAccumulator, 1000);\n\n window.addEventListener('focus', onFocus, { passive: true });\n window.addEventListener('blur', onBlur, { passive: true });\n window.addEventListener('pageshow', onPageShow, { passive: true });\n window.addEventListener('pagehide', onPageHide, { passive: true });\n window.addEventListener('scroll', onScroll, { passive: true });\n document.addEventListener('visibilitychange', onVisibilityChange, { passive: true });\n\n // save checkpoint\n checkpointEvents.forEach((event) => {\n window.addEventListener(event, checkpoint, { passive: true, capture: true });\n });\n\n return () => {\n window.removeEventListener('focus', onFocus);\n window.removeEventListener('blur', onBlur);\n window.removeEventListener('pageshow', onPageShow);\n window.removeEventListener('pagehide', onPageHide);\n window.removeEventListener('scroll', onScroll);\n document.removeEventListener('visibilitychange', onVisibilityChange);\n\n checkpointEvents.forEach((event) => {\n window.removeEventListener(event, checkpoint);\n });\n\n onScroll.cancel();\n checkpoint.cancel();\n };\n }, []);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -23,39 +23,47 @@ __export(ignored_events_exports, {
|
|
|
23
23
|
IGNORED_EVENTS: () => IGNORED_EVENTS
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(ignored_events_exports);
|
|
26
|
-
var
|
|
27
|
-
var
|
|
28
|
-
|
|
29
|
-
"first_open",
|
|
26
|
+
var METRICS_EVENTS = ["CLS", "FCP", "FID", "INP", "LCP", "TTFB"];
|
|
27
|
+
var ENHANCED_MEASUREMENT_EVENTS = [
|
|
28
|
+
// Page views
|
|
30
29
|
"page_view",
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
// Scrolls: the first time a user reaches the bottom of each page
|
|
31
|
+
// (i.e., when a 90% vertical depth becomes visible)
|
|
33
32
|
"scroll",
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
// Outbound clicks
|
|
34
|
+
"click",
|
|
35
|
+
// Site search
|
|
36
|
+
"view_search_results",
|
|
37
|
+
// Video engagement
|
|
38
|
+
"video_start",
|
|
39
|
+
"video_progress",
|
|
40
|
+
"video_complete",
|
|
41
|
+
// File downloads
|
|
42
|
+
"file_download",
|
|
43
|
+
// Form interactions
|
|
44
|
+
"form_start",
|
|
45
|
+
"form_submit"
|
|
36
46
|
];
|
|
37
|
-
var
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
var AUTOMATICALLY_COLLECTED_EVENTS = [
|
|
48
|
+
...ENHANCED_MEASUREMENT_EVENTS,
|
|
49
|
+
"first_visit",
|
|
50
|
+
"first_open",
|
|
51
|
+
// ref: https://support.google.com/analytics/answer/9234069
|
|
52
|
+
// 'in_app_purchase',
|
|
43
53
|
"notification_dismiss",
|
|
44
54
|
"notification_foreground",
|
|
45
55
|
"notification_open",
|
|
46
56
|
"notification_receive",
|
|
47
|
-
"notification_send"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
...fileDownloads,
|
|
56
|
-
...formInteractions,
|
|
57
|
-
...notification
|
|
57
|
+
"notification_send",
|
|
58
|
+
/**
|
|
59
|
+
* Note: The 'screen_view' event is automatically sent only when using Android or iOS native SDKs.
|
|
60
|
+
* If you are using React Native, you need to send this event manually; it should not be ignored.
|
|
61
|
+
* */
|
|
62
|
+
// 'screen_view',
|
|
63
|
+
"session_start",
|
|
64
|
+
"user_engagement"
|
|
58
65
|
];
|
|
66
|
+
var IGNORED_EVENTS = [...METRICS_EVENTS, ...AUTOMATICALLY_COLLECTED_EVENTS];
|
|
59
67
|
// Annotate the CommonJS export names for ESM import in node:
|
|
60
68
|
0 && (module.exports = {
|
|
61
69
|
IGNORED_EVENTS
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/third-parties/ignored-events.ts"],"sourcesContent":["/**\n * Automatically collected events: https://support.google.com/analytics/answer/9234069\n * Enhanced measurement events: https://support.google.com/analytics/answer/9216061\n */\nconst
|
|
1
|
+
{"version":3,"sources":["../../src/third-parties/ignored-events.ts"],"sourcesContent":["const METRICS_EVENTS = ['CLS', 'FCP', 'FID', 'INP', 'LCP', 'TTFB'];\n\n/**\n * Automatically collected events: https://support.google.com/analytics/answer/9234069\n * Enhanced measurement events: https://support.google.com/analytics/answer/9216061\n */\nconst ENHANCED_MEASUREMENT_EVENTS = [\n // Page views\n 'page_view',\n // Scrolls: the first time a user reaches the bottom of each page\n // (i.e., when a 90% vertical depth becomes visible)\n 'scroll',\n // Outbound clicks\n 'click',\n // Site search\n 'view_search_results',\n // Video engagement\n 'video_start',\n 'video_progress',\n 'video_complete',\n // File downloads\n 'file_download',\n // Form interactions\n 'form_start',\n 'form_submit',\n];\n\nconst AUTOMATICALLY_COLLECTED_EVENTS = [\n ...ENHANCED_MEASUREMENT_EVENTS,\n 'first_visit',\n 'first_open',\n // ref: https://support.google.com/analytics/answer/9234069\n // 'in_app_purchase',\n 'notification_dismiss',\n 'notification_foreground',\n 'notification_open',\n 'notification_receive',\n 'notification_send',\n /**\n * Note: The 'screen_view' event is automatically sent only when using Android or iOS native SDKs.\n * If you are using React Native, you need to send this event manually; it should not be ignored.\n * */\n // 'screen_view',\n 'session_start',\n 'user_engagement',\n];\n\nexport const IGNORED_EVENTS = [...METRICS_EVENTS, ...AUTOMATICALLY_COLLECTED_EVENTS];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAM,iBAAiB,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,MAAM;AAMjE,IAAM,8BAA8B;AAAA;AAAA,EAElC;AAAA;AAAA;AAAA,EAGA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EACA;AACF;AAEA,IAAM,iCAAiC;AAAA,EACrC,GAAG;AAAA,EACH;AAAA,EACA;AAAA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA;AAAA,EACA;AACF;AAEO,IAAM,iBAAiB,CAAC,GAAG,gBAAgB,GAAG,8BAA8B;","names":[]}
|
|
@@ -1,37 +1,45 @@
|
|
|
1
1
|
// src/third-parties/ignored-events.ts
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
|
|
5
|
-
"first_open",
|
|
2
|
+
var METRICS_EVENTS = ["CLS", "FCP", "FID", "INP", "LCP", "TTFB"];
|
|
3
|
+
var ENHANCED_MEASUREMENT_EVENTS = [
|
|
4
|
+
// Page views
|
|
6
5
|
"page_view",
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
// Scrolls: the first time a user reaches the bottom of each page
|
|
7
|
+
// (i.e., when a 90% vertical depth becomes visible)
|
|
9
8
|
"scroll",
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
// Outbound clicks
|
|
10
|
+
"click",
|
|
11
|
+
// Site search
|
|
12
|
+
"view_search_results",
|
|
13
|
+
// Video engagement
|
|
14
|
+
"video_start",
|
|
15
|
+
"video_progress",
|
|
16
|
+
"video_complete",
|
|
17
|
+
// File downloads
|
|
18
|
+
"file_download",
|
|
19
|
+
// Form interactions
|
|
20
|
+
"form_start",
|
|
21
|
+
"form_submit"
|
|
12
22
|
];
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
var AUTOMATICALLY_COLLECTED_EVENTS = [
|
|
24
|
+
...ENHANCED_MEASUREMENT_EVENTS,
|
|
25
|
+
"first_visit",
|
|
26
|
+
"first_open",
|
|
27
|
+
// ref: https://support.google.com/analytics/answer/9234069
|
|
28
|
+
// 'in_app_purchase',
|
|
19
29
|
"notification_dismiss",
|
|
20
30
|
"notification_foreground",
|
|
21
31
|
"notification_open",
|
|
22
32
|
"notification_receive",
|
|
23
|
-
"notification_send"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
...fileDownloads,
|
|
32
|
-
...formInteractions,
|
|
33
|
-
...notification
|
|
33
|
+
"notification_send",
|
|
34
|
+
/**
|
|
35
|
+
* Note: The 'screen_view' event is automatically sent only when using Android or iOS native SDKs.
|
|
36
|
+
* If you are using React Native, you need to send this event manually; it should not be ignored.
|
|
37
|
+
* */
|
|
38
|
+
// 'screen_view',
|
|
39
|
+
"session_start",
|
|
40
|
+
"user_engagement"
|
|
34
41
|
];
|
|
42
|
+
var IGNORED_EVENTS = [...METRICS_EVENTS, ...AUTOMATICALLY_COLLECTED_EVENTS];
|
|
35
43
|
export {
|
|
36
44
|
IGNORED_EVENTS
|
|
37
45
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/third-parties/ignored-events.ts"],"sourcesContent":["/**\n * Automatically collected events: https://support.google.com/analytics/answer/9234069\n * Enhanced measurement events: https://support.google.com/analytics/answer/9216061\n */\nconst
|
|
1
|
+
{"version":3,"sources":["../../src/third-parties/ignored-events.ts"],"sourcesContent":["const METRICS_EVENTS = ['CLS', 'FCP', 'FID', 'INP', 'LCP', 'TTFB'];\n\n/**\n * Automatically collected events: https://support.google.com/analytics/answer/9234069\n * Enhanced measurement events: https://support.google.com/analytics/answer/9216061\n */\nconst ENHANCED_MEASUREMENT_EVENTS = [\n // Page views\n 'page_view',\n // Scrolls: the first time a user reaches the bottom of each page\n // (i.e., when a 90% vertical depth becomes visible)\n 'scroll',\n // Outbound clicks\n 'click',\n // Site search\n 'view_search_results',\n // Video engagement\n 'video_start',\n 'video_progress',\n 'video_complete',\n // File downloads\n 'file_download',\n // Form interactions\n 'form_start',\n 'form_submit',\n];\n\nconst AUTOMATICALLY_COLLECTED_EVENTS = [\n ...ENHANCED_MEASUREMENT_EVENTS,\n 'first_visit',\n 'first_open',\n // ref: https://support.google.com/analytics/answer/9234069\n // 'in_app_purchase',\n 'notification_dismiss',\n 'notification_foreground',\n 'notification_open',\n 'notification_receive',\n 'notification_send',\n /**\n * Note: The 'screen_view' event is automatically sent only when using Android or iOS native SDKs.\n * If you are using React Native, you need to send this event manually; it should not be ignored.\n * */\n // 'screen_view',\n 'session_start',\n 'user_engagement',\n];\n\nexport const IGNORED_EVENTS = [...METRICS_EVENTS, ...AUTOMATICALLY_COLLECTED_EVENTS];\n"],"mappings":";AAAA,IAAM,iBAAiB,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,MAAM;AAMjE,IAAM,8BAA8B;AAAA;AAAA,EAElC;AAAA;AAAA;AAAA,EAGA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EACA;AACF;AAEA,IAAM,iCAAiC;AAAA,EACrC,GAAG;AAAA,EACH;AAAA,EACA;AAAA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA;AAAA,EACA;AACF;AAEO,IAAM,iBAAiB,CAAC,GAAG,gBAAgB,GAAG,8BAA8B;","names":[]}
|