@arthurreira/analytics 0.15.0 → 0.16.0
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/client.d.ts +2 -5
- package/dist/client.js +3 -61
- package/package.json +38 -32
package/dist/client.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
interface AnalyticsProps {
|
|
2
2
|
apiKey: string;
|
|
3
3
|
apiUrl: string;
|
|
4
|
-
wsUrl?: string;
|
|
5
4
|
}
|
|
6
|
-
declare function Analytics({ apiKey, apiUrl
|
|
5
|
+
declare function Analytics({ apiKey, apiUrl }: AnalyticsProps): null;
|
|
7
6
|
|
|
8
7
|
interface ExceptionFields {
|
|
9
8
|
exception_type: string;
|
|
@@ -11,9 +10,7 @@ interface ExceptionFields {
|
|
|
11
10
|
stack_trace: string | null;
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
declare function useAnalytics(apiUrl: string, apiKey: string
|
|
15
|
-
wsUrl?: string;
|
|
16
|
-
}): {
|
|
13
|
+
declare function useAnalytics(apiUrl: string, apiKey: string): {
|
|
17
14
|
trackPageview: (path: string) => void;
|
|
18
15
|
trackClick: (e: MouseEvent, element: HTMLElement) => void;
|
|
19
16
|
trackScroll: (depth: number) => void;
|
package/dist/client.js
CHANGED
|
@@ -130,60 +130,6 @@ async function trackCTA(apiUrl, apiKey, sessionId, path, ctaId, ctaVariant) {
|
|
|
130
130
|
});
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
// src/lib/presence.ts
|
|
134
|
-
var DEFAULT_WS_URL = "wss://edge.arthurreira.dev/realtime";
|
|
135
|
-
function connectPresence(apiKey, sessionId, wsUrl = DEFAULT_WS_URL) {
|
|
136
|
-
if (typeof WebSocket === "undefined") {
|
|
137
|
-
return { disconnect: () => {
|
|
138
|
-
} };
|
|
139
|
-
}
|
|
140
|
-
let ws = null;
|
|
141
|
-
let attempts = 0;
|
|
142
|
-
let intentionalClose = false;
|
|
143
|
-
let retryTimer = null;
|
|
144
|
-
let targetUrl;
|
|
145
|
-
try {
|
|
146
|
-
const u = new URL(wsUrl);
|
|
147
|
-
u.searchParams.set("api_key", apiKey);
|
|
148
|
-
u.searchParams.set("session_id", sessionId);
|
|
149
|
-
targetUrl = u.toString();
|
|
150
|
-
} catch {
|
|
151
|
-
return { disconnect: () => {
|
|
152
|
-
} };
|
|
153
|
-
}
|
|
154
|
-
function connect() {
|
|
155
|
-
try {
|
|
156
|
-
ws = new WebSocket(targetUrl);
|
|
157
|
-
} catch {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
ws.onopen = () => {
|
|
161
|
-
attempts = 0;
|
|
162
|
-
ws.send(JSON.stringify({ type: "join", api_key: apiKey, session_id: sessionId }));
|
|
163
|
-
};
|
|
164
|
-
ws.onclose = () => {
|
|
165
|
-
if (intentionalClose || attempts >= 3) return;
|
|
166
|
-
const delay = Math.pow(2, attempts) * 1e3;
|
|
167
|
-
attempts++;
|
|
168
|
-
retryTimer = setTimeout(connect, delay);
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
connect();
|
|
172
|
-
return {
|
|
173
|
-
disconnect: () => {
|
|
174
|
-
intentionalClose = true;
|
|
175
|
-
if (retryTimer !== null) {
|
|
176
|
-
clearTimeout(retryTimer);
|
|
177
|
-
retryTimer = null;
|
|
178
|
-
}
|
|
179
|
-
if (ws) {
|
|
180
|
-
ws.close();
|
|
181
|
-
ws = null;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
|
|
187
133
|
// src/hooks/useAnalytics.ts
|
|
188
134
|
var SESSION_EXPIRY_MINUTES = 30;
|
|
189
135
|
var _sessionFlight = null;
|
|
@@ -210,11 +156,10 @@ async function getOrCreateSession(apiUrl, apiKey, visitorId) {
|
|
|
210
156
|
});
|
|
211
157
|
return _sessionFlight;
|
|
212
158
|
}
|
|
213
|
-
function useAnalytics(apiUrl, apiKey
|
|
159
|
+
function useAnalytics(apiUrl, apiKey) {
|
|
214
160
|
const sessionId = useRef(null);
|
|
215
161
|
const pendingEvents = useRef([]);
|
|
216
162
|
const pathname = useRef(typeof window !== "undefined" ? window?.location?.pathname ?? "" : "");
|
|
217
|
-
const presence = useRef(null);
|
|
218
163
|
const hasSentEnd = useRef(false);
|
|
219
164
|
useEffect(() => {
|
|
220
165
|
if (typeof window === "undefined") return;
|
|
@@ -224,7 +169,6 @@ function useAnalytics(apiUrl, apiKey, options) {
|
|
|
224
169
|
getOrCreateSession(apiUrl, apiKey, visitor_id).then((id) => {
|
|
225
170
|
if (cancelled) return;
|
|
226
171
|
sessionId.current = id;
|
|
227
|
-
presence.current = connectPresence(apiKey, id, options?.wsUrl);
|
|
228
172
|
pendingEvents.current.forEach((fn) => fn());
|
|
229
173
|
pendingEvents.current = [];
|
|
230
174
|
});
|
|
@@ -237,8 +181,6 @@ function useAnalytics(apiUrl, apiKey, options) {
|
|
|
237
181
|
const sendEnd = () => {
|
|
238
182
|
if (!sessionId.current || hasSentEnd.current) return;
|
|
239
183
|
hasSentEnd.current = true;
|
|
240
|
-
presence.current?.disconnect();
|
|
241
|
-
presence.current = null;
|
|
242
184
|
navigator.sendBeacon(`${apiUrl}/sessions/${sessionId.current}/end`);
|
|
243
185
|
localStorage.removeItem("af_session_id");
|
|
244
186
|
localStorage.removeItem("af_session_last_activity");
|
|
@@ -291,8 +233,8 @@ function useAnalytics(apiUrl, apiKey, options) {
|
|
|
291
233
|
}
|
|
292
234
|
|
|
293
235
|
// src/components/Analytics.tsx
|
|
294
|
-
function Analytics({ apiKey, apiUrl
|
|
295
|
-
const { trackPageview: trackPageview2, trackClick: trackClick2, trackScroll: trackScroll2, trackCopy: trackCopy2, trackException: trackException2 } = useAnalytics(apiUrl, apiKey
|
|
236
|
+
function Analytics({ apiKey, apiUrl }) {
|
|
237
|
+
const { trackPageview: trackPageview2, trackClick: trackClick2, trackScroll: trackScroll2, trackCopy: trackCopy2, trackException: trackException2 } = useAnalytics(apiUrl, apiKey);
|
|
296
238
|
const lastTracked = useRef2(null);
|
|
297
239
|
const lastScrollDepth = useRef2(0);
|
|
298
240
|
const pathname = typeof window !== "undefined" ? window.location.pathname : "";
|
package/package.json
CHANGED
|
@@ -1,35 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@arthurreira/analytics",
|
|
3
|
+
"version": "0.16.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "tsup",
|
|
7
|
+
"prepare": "tsup",
|
|
8
|
+
"dev": "tsup src/index.ts --format esm --dts --watch"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js"
|
|
8
14
|
},
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
"import": "./dist/index.js"
|
|
13
|
-
},
|
|
14
|
-
"./client": {
|
|
15
|
-
"types": "./dist/client.d.ts",
|
|
16
|
-
"import": "./dist/client.js"
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"sideEffects": false,
|
|
20
|
-
"files": [
|
|
21
|
-
"dist"
|
|
22
|
-
],
|
|
23
|
-
"description": "Analytics SDK for af-analytics (browser client + helpers)",
|
|
24
|
-
"license": "MIT",
|
|
25
|
-
"dependencies": {},
|
|
26
|
-
"devDependencies": {
|
|
27
|
-
"tsup": "^8.5.1",
|
|
28
|
-
"typescript": "^5.9.2",
|
|
29
|
-
"@types/react": "^19.0.0"
|
|
30
|
-
},
|
|
31
|
-
"peerDependencies": {
|
|
32
|
-
"next": "^14.0.0 || ^15.0.0 || ^16.0.0",
|
|
33
|
-
"react": "^18.0.0 || ^19.0.0"
|
|
15
|
+
"./client": {
|
|
16
|
+
"types": "./dist/client.d.ts",
|
|
17
|
+
"import": "./dist/client.js"
|
|
34
18
|
}
|
|
19
|
+
},
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"description": "Analytics SDK for af-analytics (browser client + helpers)",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
28
|
+
"@testing-library/react": "^16.3.2",
|
|
29
|
+
"@types/react": "^19.0.0",
|
|
30
|
+
"jsdom": "^29.1.1",
|
|
31
|
+
"react": "^19.2.6",
|
|
32
|
+
"react-dom": "^19.2.6",
|
|
33
|
+
"tsup": "^8.5.1",
|
|
34
|
+
"typescript": "^5.9.2",
|
|
35
|
+
"vitest": "^4.1.7"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"next": "^14.0.0 || ^15.0.0 || ^16.0.0",
|
|
39
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
40
|
+
}
|
|
35
41
|
}
|