@getdevteam/analytics-web 0.1.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/index.cjs +263 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +35 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +231 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
WEB_SDK_NAME: () => WEB_SDK_NAME,
|
|
24
|
+
WEB_SDK_VERSION: () => WEB_SDK_VERSION,
|
|
25
|
+
browserFromUserAgent: () => browserFromUserAgent,
|
|
26
|
+
collectWebContext: () => collectWebContext,
|
|
27
|
+
createAnalytics: () => createAnalytics,
|
|
28
|
+
createBrowserStorage: () => createBrowserStorage,
|
|
29
|
+
currentPageProperties: () => currentPageProperties,
|
|
30
|
+
detectDeviceType: () => detectDeviceType,
|
|
31
|
+
installPageviewTracking: () => installPageviewTracking,
|
|
32
|
+
osFromUserAgent: () => osFromUserAgent
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(index_exports);
|
|
35
|
+
var import_analytics_core2 = require("@getdevteam/analytics-core");
|
|
36
|
+
|
|
37
|
+
// src/context.ts
|
|
38
|
+
function browserFromUserAgent(ua) {
|
|
39
|
+
if (/Edg(e|A|iOS)?\//.test(ua)) return "Edge";
|
|
40
|
+
if (/Firefox\/|FxiOS\//.test(ua)) return "Firefox";
|
|
41
|
+
if (/CriOS\/|Chrome\//.test(ua)) return "Chrome";
|
|
42
|
+
if (/Safari\//.test(ua)) return "Safari";
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
45
|
+
function osFromUserAgent(ua, platform) {
|
|
46
|
+
if (/Windows/.test(ua)) {
|
|
47
|
+
const match = /Windows NT ([\d.]+)/.exec(ua);
|
|
48
|
+
return { os_name: "Windows", ...match?.[1] ? { os_version: match[1] } : {} };
|
|
49
|
+
}
|
|
50
|
+
if (/iPhone|iPad|iPod/.test(ua)) {
|
|
51
|
+
const match = /OS (\d+[_.]\d+(?:[_.]\d+)?)/.exec(ua);
|
|
52
|
+
return { os_name: "iOS", ...match?.[1] ? { os_version: match[1].replace(/_/g, ".") } : {} };
|
|
53
|
+
}
|
|
54
|
+
if (/Android/.test(ua)) {
|
|
55
|
+
const match = /Android ([\d.]+)/.exec(ua);
|
|
56
|
+
return { os_name: "Android", ...match?.[1] ? { os_version: match[1] } : {} };
|
|
57
|
+
}
|
|
58
|
+
if (/Mac OS X|Macintosh/.test(ua) || (platform ?? "").startsWith("Mac")) {
|
|
59
|
+
const match = /Mac OS X (\d+[_.]\d+(?:[_.]\d+)?)/.exec(ua);
|
|
60
|
+
return { os_name: "macOS", ...match?.[1] ? { os_version: match[1].replace(/_/g, ".") } : {} };
|
|
61
|
+
}
|
|
62
|
+
if (/Linux/.test(ua) || (platform ?? "").startsWith("Linux")) {
|
|
63
|
+
return { os_name: "Linux" };
|
|
64
|
+
}
|
|
65
|
+
return {};
|
|
66
|
+
}
|
|
67
|
+
function detectDeviceType(win) {
|
|
68
|
+
try {
|
|
69
|
+
const coarse = typeof win.matchMedia === "function" && win.matchMedia("(pointer: coarse)").matches;
|
|
70
|
+
if (!coarse) return "desktop";
|
|
71
|
+
const width = win.innerWidth || win.screen?.width || 0;
|
|
72
|
+
return width >= 768 ? "tablet" : "mobile";
|
|
73
|
+
} catch {
|
|
74
|
+
return "desktop";
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function collectWebContext() {
|
|
78
|
+
if (typeof window === "undefined" || typeof navigator === "undefined") {
|
|
79
|
+
return { platform: "web" };
|
|
80
|
+
}
|
|
81
|
+
const ua = navigator.userAgent ?? "";
|
|
82
|
+
const context = { platform: "web" };
|
|
83
|
+
const browser = browserFromUserAgent(ua);
|
|
84
|
+
if (browser !== void 0) context.browser = browser;
|
|
85
|
+
Object.assign(context, osFromUserAgent(ua, navigator.platform));
|
|
86
|
+
context.device_type = detectDeviceType(window);
|
|
87
|
+
if (navigator.language) context.locale = navigator.language;
|
|
88
|
+
if (window.screen) {
|
|
89
|
+
context.screen = { w: window.screen.width ?? 0, h: window.screen.height ?? 0 };
|
|
90
|
+
}
|
|
91
|
+
return context;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// src/pageviews.ts
|
|
95
|
+
function currentPageProperties() {
|
|
96
|
+
return {
|
|
97
|
+
url: window.location.href,
|
|
98
|
+
title: document.title
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function installPageviewTracking(client) {
|
|
102
|
+
const sendPageview = () => client.page(currentPageProperties());
|
|
103
|
+
const history = window.history;
|
|
104
|
+
const originalPushState = history.pushState.bind(history);
|
|
105
|
+
const originalReplaceState = history.replaceState.bind(history);
|
|
106
|
+
history.pushState = (...args) => {
|
|
107
|
+
originalPushState(...args);
|
|
108
|
+
sendPageview();
|
|
109
|
+
};
|
|
110
|
+
history.replaceState = (...args) => {
|
|
111
|
+
originalReplaceState(...args);
|
|
112
|
+
sendPageview();
|
|
113
|
+
};
|
|
114
|
+
window.addEventListener("popstate", sendPageview);
|
|
115
|
+
sendPageview();
|
|
116
|
+
return () => {
|
|
117
|
+
history.pushState = originalPushState;
|
|
118
|
+
history.replaceState = originalReplaceState;
|
|
119
|
+
window.removeEventListener("popstate", sendPageview);
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// src/storage.ts
|
|
124
|
+
var import_analytics_core = require("@getdevteam/analytics-core");
|
|
125
|
+
function resolveLocalStorage() {
|
|
126
|
+
try {
|
|
127
|
+
if (typeof window === "undefined" || !window.localStorage) return void 0;
|
|
128
|
+
const probe = "__devteam_analytics_probe__";
|
|
129
|
+
window.localStorage.setItem(probe, "1");
|
|
130
|
+
window.localStorage.removeItem(probe);
|
|
131
|
+
return window.localStorage;
|
|
132
|
+
} catch {
|
|
133
|
+
return void 0;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function createBrowserStorage(resolve = resolveLocalStorage) {
|
|
137
|
+
const localStorage = resolve();
|
|
138
|
+
if (!localStorage) return (0, import_analytics_core.createMemoryStorage)();
|
|
139
|
+
return {
|
|
140
|
+
getItem: (key) => {
|
|
141
|
+
try {
|
|
142
|
+
return localStorage.getItem(key);
|
|
143
|
+
} catch {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
setItem: (key, value) => {
|
|
148
|
+
try {
|
|
149
|
+
localStorage.setItem(key, value);
|
|
150
|
+
} catch {
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
removeItem: (key) => {
|
|
154
|
+
try {
|
|
155
|
+
localStorage.removeItem(key);
|
|
156
|
+
} catch {
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// src/index.ts
|
|
163
|
+
var WEB_SDK_NAME = "@getdevteam/analytics-web";
|
|
164
|
+
var WEB_SDK_VERSION = "0.1.0";
|
|
165
|
+
function createAnalytics(config) {
|
|
166
|
+
let finalFlush = false;
|
|
167
|
+
const baseFetch = config.fetch ?? defaultBrowserFetch();
|
|
168
|
+
const client = (0, import_analytics_core2.createClient)({
|
|
169
|
+
...config,
|
|
170
|
+
storage: config.storage ?? createBrowserStorage(),
|
|
171
|
+
fetch: (url, init) => {
|
|
172
|
+
if (finalFlush) return sendOnHide(url, init, config.key, baseFetch);
|
|
173
|
+
if (baseFetch) return baseFetch(url, init);
|
|
174
|
+
return Promise.reject(new Error("fetch is not available in this environment"));
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
client.setContext({
|
|
178
|
+
sdk_name: WEB_SDK_NAME,
|
|
179
|
+
sdk_version: WEB_SDK_VERSION,
|
|
180
|
+
...collectWebContext(),
|
|
181
|
+
...config.context
|
|
182
|
+
});
|
|
183
|
+
const teardowns = [];
|
|
184
|
+
if (typeof window !== "undefined") {
|
|
185
|
+
const flushOnHide = () => {
|
|
186
|
+
finalFlush = true;
|
|
187
|
+
void client.flush().finally(() => {
|
|
188
|
+
finalFlush = false;
|
|
189
|
+
});
|
|
190
|
+
};
|
|
191
|
+
const onPageHide = () => flushOnHide();
|
|
192
|
+
const onVisibilityChange = () => {
|
|
193
|
+
if (document.visibilityState === "hidden") flushOnHide();
|
|
194
|
+
};
|
|
195
|
+
window.addEventListener("pagehide", onPageHide);
|
|
196
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
197
|
+
teardowns.push(() => {
|
|
198
|
+
window.removeEventListener("pagehide", onPageHide);
|
|
199
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
200
|
+
});
|
|
201
|
+
if (config.autoCaptureErrors !== false) {
|
|
202
|
+
const onError = (event) => {
|
|
203
|
+
client.captureError(event.error ?? event.message, { source: "window.onerror" });
|
|
204
|
+
};
|
|
205
|
+
const onRejection = (event) => {
|
|
206
|
+
const reason = event.reason;
|
|
207
|
+
client.captureError(reason ?? "unhandled promise rejection", {
|
|
208
|
+
source: "unhandledrejection"
|
|
209
|
+
});
|
|
210
|
+
};
|
|
211
|
+
window.addEventListener("error", onError);
|
|
212
|
+
window.addEventListener("unhandledrejection", onRejection);
|
|
213
|
+
teardowns.push(() => {
|
|
214
|
+
window.removeEventListener("error", onError);
|
|
215
|
+
window.removeEventListener("unhandledrejection", onRejection);
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
if (config.trackPageviews === true) {
|
|
219
|
+
teardowns.push(installPageviewTracking(client));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
...client,
|
|
224
|
+
shutdown: async () => {
|
|
225
|
+
for (const teardown of teardowns.splice(0)) {
|
|
226
|
+
teardown();
|
|
227
|
+
}
|
|
228
|
+
await client.shutdown();
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function defaultBrowserFetch() {
|
|
233
|
+
if (typeof fetch !== "function") return void 0;
|
|
234
|
+
return (url, init) => fetch(url, init);
|
|
235
|
+
}
|
|
236
|
+
function sendOnHide(url, init, key, baseFetch) {
|
|
237
|
+
if (baseFetch) {
|
|
238
|
+
return baseFetch(url, { ...init, keepalive: true });
|
|
239
|
+
}
|
|
240
|
+
if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
|
|
241
|
+
const beaconUrl = `${url}${url.includes("?") ? "&" : "?"}key=${encodeURIComponent(key)}`;
|
|
242
|
+
const delivered = navigator.sendBeacon(
|
|
243
|
+
beaconUrl,
|
|
244
|
+
new Blob([init.body], { type: "application/json" })
|
|
245
|
+
);
|
|
246
|
+
return Promise.resolve({ ok: delivered, status: delivered ? 202 : 503 });
|
|
247
|
+
}
|
|
248
|
+
return Promise.reject(new Error("no transport available for final flush"));
|
|
249
|
+
}
|
|
250
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
251
|
+
0 && (module.exports = {
|
|
252
|
+
WEB_SDK_NAME,
|
|
253
|
+
WEB_SDK_VERSION,
|
|
254
|
+
browserFromUserAgent,
|
|
255
|
+
collectWebContext,
|
|
256
|
+
createAnalytics,
|
|
257
|
+
createBrowserStorage,
|
|
258
|
+
currentPageProperties,
|
|
259
|
+
detectDeviceType,
|
|
260
|
+
installPageviewTracking,
|
|
261
|
+
osFromUserAgent
|
|
262
|
+
});
|
|
263
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/context.ts","../src/pageviews.ts","../src/storage.ts"],"sourcesContent":["import {\n createClient,\n type AnalyticsClient,\n type ClientConfig,\n type EventContext,\n type FetchLike,\n type FetchRequestInit,\n type FetchResponseLike,\n} from \"@getdevteam/analytics-core\";\nimport { collectWebContext } from \"./context\";\nimport { installPageviewTracking } from \"./pageviews\";\nimport { createBrowserStorage } from \"./storage\";\n\nexport const WEB_SDK_NAME = \"@getdevteam/analytics-web\";\nexport const WEB_SDK_VERSION = \"0.1.0\";\n\nexport interface WebAnalyticsConfig extends ClientConfig {\n autoCaptureErrors?: boolean;\n trackPageviews?: boolean;\n context?: Partial<EventContext>;\n}\n\nexport function createAnalytics(config: WebAnalyticsConfig): AnalyticsClient {\n let finalFlush = false;\n const baseFetch = config.fetch ?? defaultBrowserFetch();\n\n const client = createClient({\n ...config,\n storage: config.storage ?? createBrowserStorage(),\n fetch: (url, init) => {\n if (finalFlush) return sendOnHide(url, init, config.key, baseFetch);\n if (baseFetch) return baseFetch(url, init);\n return Promise.reject(new Error(\"fetch is not available in this environment\"));\n },\n });\n\n client.setContext({\n sdk_name: WEB_SDK_NAME,\n sdk_version: WEB_SDK_VERSION,\n ...collectWebContext(),\n ...config.context,\n });\n\n const teardowns: Array<() => void> = [];\n\n if (typeof window !== \"undefined\") {\n const flushOnHide = (): void => {\n finalFlush = true;\n void client.flush().finally(() => {\n finalFlush = false;\n });\n };\n const onPageHide = (): void => flushOnHide();\n const onVisibilityChange = (): void => {\n if (document.visibilityState === \"hidden\") flushOnHide();\n };\n window.addEventListener(\"pagehide\", onPageHide);\n document.addEventListener(\"visibilitychange\", onVisibilityChange);\n teardowns.push(() => {\n window.removeEventListener(\"pagehide\", onPageHide);\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n });\n\n if (config.autoCaptureErrors !== false) {\n const onError = (event: ErrorEvent): void => {\n client.captureError(event.error ?? event.message, { source: \"window.onerror\" });\n };\n const onRejection = (event: Event): void => {\n const reason = (event as { reason?: unknown }).reason;\n client.captureError(reason ?? \"unhandled promise rejection\", {\n source: \"unhandledrejection\",\n });\n };\n window.addEventListener(\"error\", onError);\n window.addEventListener(\"unhandledrejection\", onRejection);\n teardowns.push(() => {\n window.removeEventListener(\"error\", onError);\n window.removeEventListener(\"unhandledrejection\", onRejection);\n });\n }\n\n if (config.trackPageviews === true) {\n teardowns.push(installPageviewTracking(client));\n }\n }\n\n return {\n ...client,\n shutdown: async () => {\n for (const teardown of teardowns.splice(0)) {\n teardown();\n }\n await client.shutdown();\n },\n };\n}\n\nfunction defaultBrowserFetch(): FetchLike | undefined {\n if (typeof fetch !== \"function\") return undefined;\n return (url, init) => fetch(url, init);\n}\n\nfunction sendOnHide(\n url: string,\n init: FetchRequestInit,\n key: string,\n baseFetch: FetchLike | undefined,\n): Promise<FetchResponseLike> {\n if (baseFetch) {\n return baseFetch(url, { ...init, keepalive: true });\n }\n if (typeof navigator !== \"undefined\" && typeof navigator.sendBeacon === \"function\") {\n // sendBeacon cannot set headers, so the key rides as a query parameter as a last resort.\n const beaconUrl = `${url}${url.includes(\"?\") ? \"&\" : \"?\"}key=${encodeURIComponent(key)}`;\n const delivered = navigator.sendBeacon(\n beaconUrl,\n new Blob([init.body], { type: \"application/json\" }),\n );\n return Promise.resolve({ ok: delivered, status: delivered ? 202 : 503 });\n }\n return Promise.reject(new Error(\"no transport available for final flush\"));\n}\n\nexport { collectWebContext, browserFromUserAgent, osFromUserAgent, detectDeviceType } from \"./context\";\nexport { createBrowserStorage } from \"./storage\";\nexport { currentPageProperties, installPageviewTracking } from \"./pageviews\";\nexport type {\n AnalyticsClient,\n AnalyticsLogger,\n ClientConfig,\n EventContext,\n FetchLike,\n LogSeverity,\n Properties,\n StorageAdapter,\n} from \"@getdevteam/analytics-core\";\n","import type { EventContext } from \"@getdevteam/analytics-core\";\n\nexport function browserFromUserAgent(ua: string): string | undefined {\n if (/Edg(e|A|iOS)?\\//.test(ua)) return \"Edge\";\n if (/Firefox\\/|FxiOS\\//.test(ua)) return \"Firefox\";\n if (/CriOS\\/|Chrome\\//.test(ua)) return \"Chrome\";\n if (/Safari\\//.test(ua)) return \"Safari\";\n return undefined;\n}\n\nexport function osFromUserAgent(\n ua: string,\n platform?: string,\n): { os_name?: string; os_version?: string } {\n if (/Windows/.test(ua)) {\n const match = /Windows NT ([\\d.]+)/.exec(ua);\n return { os_name: \"Windows\", ...(match?.[1] ? { os_version: match[1] } : {}) };\n }\n if (/iPhone|iPad|iPod/.test(ua)) {\n const match = /OS (\\d+[_.]\\d+(?:[_.]\\d+)?)/.exec(ua);\n return { os_name: \"iOS\", ...(match?.[1] ? { os_version: match[1].replace(/_/g, \".\") } : {}) };\n }\n if (/Android/.test(ua)) {\n const match = /Android ([\\d.]+)/.exec(ua);\n return { os_name: \"Android\", ...(match?.[1] ? { os_version: match[1] } : {}) };\n }\n if (/Mac OS X|Macintosh/.test(ua) || (platform ?? \"\").startsWith(\"Mac\")) {\n const match = /Mac OS X (\\d+[_.]\\d+(?:[_.]\\d+)?)/.exec(ua);\n return { os_name: \"macOS\", ...(match?.[1] ? { os_version: match[1].replace(/_/g, \".\") } : {}) };\n }\n if (/Linux/.test(ua) || (platform ?? \"\").startsWith(\"Linux\")) {\n return { os_name: \"Linux\" };\n }\n return {};\n}\n\ninterface WindowLike {\n matchMedia?: (query: string) => { matches: boolean };\n innerWidth?: number;\n screen?: { width?: number };\n}\n\nexport function detectDeviceType(win: WindowLike): string {\n try {\n const coarse =\n typeof win.matchMedia === \"function\" && win.matchMedia(\"(pointer: coarse)\").matches;\n if (!coarse) return \"desktop\";\n const width = win.innerWidth || win.screen?.width || 0;\n return width >= 768 ? \"tablet\" : \"mobile\";\n } catch {\n return \"desktop\";\n }\n}\n\nexport function collectWebContext(): EventContext {\n if (typeof window === \"undefined\" || typeof navigator === \"undefined\") {\n return { platform: \"web\" };\n }\n const ua = navigator.userAgent ?? \"\";\n const context: EventContext = { platform: \"web\" };\n const browser = browserFromUserAgent(ua);\n if (browser !== undefined) context.browser = browser;\n Object.assign(context, osFromUserAgent(ua, navigator.platform));\n context.device_type = detectDeviceType(window);\n if (navigator.language) context.locale = navigator.language;\n if (window.screen) {\n context.screen = { w: window.screen.width ?? 0, h: window.screen.height ?? 0 };\n }\n return context;\n}\n","import type { AnalyticsClient, Properties } from \"@getdevteam/analytics-core\";\n\nexport function currentPageProperties(): Properties {\n return {\n url: window.location.href,\n title: document.title,\n };\n}\n\nexport function installPageviewTracking(client: AnalyticsClient): () => void {\n const sendPageview = (): void => client.page(currentPageProperties());\n const history = window.history;\n const originalPushState = history.pushState.bind(history);\n const originalReplaceState = history.replaceState.bind(history);\n\n history.pushState = (...args: Parameters<History[\"pushState\"]>) => {\n originalPushState(...args);\n sendPageview();\n };\n history.replaceState = (...args: Parameters<History[\"replaceState\"]>) => {\n originalReplaceState(...args);\n sendPageview();\n };\n window.addEventListener(\"popstate\", sendPageview);\n sendPageview();\n\n return () => {\n history.pushState = originalPushState;\n history.replaceState = originalReplaceState;\n window.removeEventListener(\"popstate\", sendPageview);\n };\n}\n","import { createMemoryStorage, type StorageAdapter } from \"@getdevteam/analytics-core\";\n\nexport function resolveLocalStorage(): Storage | undefined {\n try {\n if (typeof window === \"undefined\" || !window.localStorage) return undefined;\n const probe = \"__devteam_analytics_probe__\";\n window.localStorage.setItem(probe, \"1\");\n window.localStorage.removeItem(probe);\n return window.localStorage;\n } catch {\n return undefined;\n }\n}\n\nexport function createBrowserStorage(\n resolve: () => Storage | undefined = resolveLocalStorage,\n): StorageAdapter {\n const localStorage = resolve();\n if (!localStorage) return createMemoryStorage();\n return {\n getItem: (key) => {\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n },\n setItem: (key, value) => {\n try {\n localStorage.setItem(key, value);\n } catch {\n // quota or private-mode failure; queue persistence degrades gracefully\n }\n },\n removeItem: (key) => {\n try {\n localStorage.removeItem(key);\n } catch {\n // ignore\n }\n },\n };\n}\n"],"mappings":"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","names":["import_analytics_core"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { EventContext, StorageAdapter, Properties, AnalyticsClient, ClientConfig } from '@getdevteam/analytics-core';
|
|
2
|
+
export { AnalyticsClient, AnalyticsLogger, ClientConfig, EventContext, FetchLike, LogSeverity, Properties, StorageAdapter } from '@getdevteam/analytics-core';
|
|
3
|
+
|
|
4
|
+
declare function browserFromUserAgent(ua: string): string | undefined;
|
|
5
|
+
declare function osFromUserAgent(ua: string, platform?: string): {
|
|
6
|
+
os_name?: string;
|
|
7
|
+
os_version?: string;
|
|
8
|
+
};
|
|
9
|
+
interface WindowLike {
|
|
10
|
+
matchMedia?: (query: string) => {
|
|
11
|
+
matches: boolean;
|
|
12
|
+
};
|
|
13
|
+
innerWidth?: number;
|
|
14
|
+
screen?: {
|
|
15
|
+
width?: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
declare function detectDeviceType(win: WindowLike): string;
|
|
19
|
+
declare function collectWebContext(): EventContext;
|
|
20
|
+
|
|
21
|
+
declare function createBrowserStorage(resolve?: () => Storage | undefined): StorageAdapter;
|
|
22
|
+
|
|
23
|
+
declare function currentPageProperties(): Properties;
|
|
24
|
+
declare function installPageviewTracking(client: AnalyticsClient): () => void;
|
|
25
|
+
|
|
26
|
+
declare const WEB_SDK_NAME = "@getdevteam/analytics-web";
|
|
27
|
+
declare const WEB_SDK_VERSION = "0.1.0";
|
|
28
|
+
interface WebAnalyticsConfig extends ClientConfig {
|
|
29
|
+
autoCaptureErrors?: boolean;
|
|
30
|
+
trackPageviews?: boolean;
|
|
31
|
+
context?: Partial<EventContext>;
|
|
32
|
+
}
|
|
33
|
+
declare function createAnalytics(config: WebAnalyticsConfig): AnalyticsClient;
|
|
34
|
+
|
|
35
|
+
export { WEB_SDK_NAME, WEB_SDK_VERSION, type WebAnalyticsConfig, browserFromUserAgent, collectWebContext, createAnalytics, createBrowserStorage, currentPageProperties, detectDeviceType, installPageviewTracking, osFromUserAgent };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { EventContext, StorageAdapter, Properties, AnalyticsClient, ClientConfig } from '@getdevteam/analytics-core';
|
|
2
|
+
export { AnalyticsClient, AnalyticsLogger, ClientConfig, EventContext, FetchLike, LogSeverity, Properties, StorageAdapter } from '@getdevteam/analytics-core';
|
|
3
|
+
|
|
4
|
+
declare function browserFromUserAgent(ua: string): string | undefined;
|
|
5
|
+
declare function osFromUserAgent(ua: string, platform?: string): {
|
|
6
|
+
os_name?: string;
|
|
7
|
+
os_version?: string;
|
|
8
|
+
};
|
|
9
|
+
interface WindowLike {
|
|
10
|
+
matchMedia?: (query: string) => {
|
|
11
|
+
matches: boolean;
|
|
12
|
+
};
|
|
13
|
+
innerWidth?: number;
|
|
14
|
+
screen?: {
|
|
15
|
+
width?: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
declare function detectDeviceType(win: WindowLike): string;
|
|
19
|
+
declare function collectWebContext(): EventContext;
|
|
20
|
+
|
|
21
|
+
declare function createBrowserStorage(resolve?: () => Storage | undefined): StorageAdapter;
|
|
22
|
+
|
|
23
|
+
declare function currentPageProperties(): Properties;
|
|
24
|
+
declare function installPageviewTracking(client: AnalyticsClient): () => void;
|
|
25
|
+
|
|
26
|
+
declare const WEB_SDK_NAME = "@getdevteam/analytics-web";
|
|
27
|
+
declare const WEB_SDK_VERSION = "0.1.0";
|
|
28
|
+
interface WebAnalyticsConfig extends ClientConfig {
|
|
29
|
+
autoCaptureErrors?: boolean;
|
|
30
|
+
trackPageviews?: boolean;
|
|
31
|
+
context?: Partial<EventContext>;
|
|
32
|
+
}
|
|
33
|
+
declare function createAnalytics(config: WebAnalyticsConfig): AnalyticsClient;
|
|
34
|
+
|
|
35
|
+
export { WEB_SDK_NAME, WEB_SDK_VERSION, type WebAnalyticsConfig, browserFromUserAgent, collectWebContext, createAnalytics, createBrowserStorage, currentPageProperties, detectDeviceType, installPageviewTracking, osFromUserAgent };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import {
|
|
3
|
+
createClient
|
|
4
|
+
} from "@getdevteam/analytics-core";
|
|
5
|
+
|
|
6
|
+
// src/context.ts
|
|
7
|
+
function browserFromUserAgent(ua) {
|
|
8
|
+
if (/Edg(e|A|iOS)?\//.test(ua)) return "Edge";
|
|
9
|
+
if (/Firefox\/|FxiOS\//.test(ua)) return "Firefox";
|
|
10
|
+
if (/CriOS\/|Chrome\//.test(ua)) return "Chrome";
|
|
11
|
+
if (/Safari\//.test(ua)) return "Safari";
|
|
12
|
+
return void 0;
|
|
13
|
+
}
|
|
14
|
+
function osFromUserAgent(ua, platform) {
|
|
15
|
+
if (/Windows/.test(ua)) {
|
|
16
|
+
const match = /Windows NT ([\d.]+)/.exec(ua);
|
|
17
|
+
return { os_name: "Windows", ...match?.[1] ? { os_version: match[1] } : {} };
|
|
18
|
+
}
|
|
19
|
+
if (/iPhone|iPad|iPod/.test(ua)) {
|
|
20
|
+
const match = /OS (\d+[_.]\d+(?:[_.]\d+)?)/.exec(ua);
|
|
21
|
+
return { os_name: "iOS", ...match?.[1] ? { os_version: match[1].replace(/_/g, ".") } : {} };
|
|
22
|
+
}
|
|
23
|
+
if (/Android/.test(ua)) {
|
|
24
|
+
const match = /Android ([\d.]+)/.exec(ua);
|
|
25
|
+
return { os_name: "Android", ...match?.[1] ? { os_version: match[1] } : {} };
|
|
26
|
+
}
|
|
27
|
+
if (/Mac OS X|Macintosh/.test(ua) || (platform ?? "").startsWith("Mac")) {
|
|
28
|
+
const match = /Mac OS X (\d+[_.]\d+(?:[_.]\d+)?)/.exec(ua);
|
|
29
|
+
return { os_name: "macOS", ...match?.[1] ? { os_version: match[1].replace(/_/g, ".") } : {} };
|
|
30
|
+
}
|
|
31
|
+
if (/Linux/.test(ua) || (platform ?? "").startsWith("Linux")) {
|
|
32
|
+
return { os_name: "Linux" };
|
|
33
|
+
}
|
|
34
|
+
return {};
|
|
35
|
+
}
|
|
36
|
+
function detectDeviceType(win) {
|
|
37
|
+
try {
|
|
38
|
+
const coarse = typeof win.matchMedia === "function" && win.matchMedia("(pointer: coarse)").matches;
|
|
39
|
+
if (!coarse) return "desktop";
|
|
40
|
+
const width = win.innerWidth || win.screen?.width || 0;
|
|
41
|
+
return width >= 768 ? "tablet" : "mobile";
|
|
42
|
+
} catch {
|
|
43
|
+
return "desktop";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function collectWebContext() {
|
|
47
|
+
if (typeof window === "undefined" || typeof navigator === "undefined") {
|
|
48
|
+
return { platform: "web" };
|
|
49
|
+
}
|
|
50
|
+
const ua = navigator.userAgent ?? "";
|
|
51
|
+
const context = { platform: "web" };
|
|
52
|
+
const browser = browserFromUserAgent(ua);
|
|
53
|
+
if (browser !== void 0) context.browser = browser;
|
|
54
|
+
Object.assign(context, osFromUserAgent(ua, navigator.platform));
|
|
55
|
+
context.device_type = detectDeviceType(window);
|
|
56
|
+
if (navigator.language) context.locale = navigator.language;
|
|
57
|
+
if (window.screen) {
|
|
58
|
+
context.screen = { w: window.screen.width ?? 0, h: window.screen.height ?? 0 };
|
|
59
|
+
}
|
|
60
|
+
return context;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/pageviews.ts
|
|
64
|
+
function currentPageProperties() {
|
|
65
|
+
return {
|
|
66
|
+
url: window.location.href,
|
|
67
|
+
title: document.title
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function installPageviewTracking(client) {
|
|
71
|
+
const sendPageview = () => client.page(currentPageProperties());
|
|
72
|
+
const history = window.history;
|
|
73
|
+
const originalPushState = history.pushState.bind(history);
|
|
74
|
+
const originalReplaceState = history.replaceState.bind(history);
|
|
75
|
+
history.pushState = (...args) => {
|
|
76
|
+
originalPushState(...args);
|
|
77
|
+
sendPageview();
|
|
78
|
+
};
|
|
79
|
+
history.replaceState = (...args) => {
|
|
80
|
+
originalReplaceState(...args);
|
|
81
|
+
sendPageview();
|
|
82
|
+
};
|
|
83
|
+
window.addEventListener("popstate", sendPageview);
|
|
84
|
+
sendPageview();
|
|
85
|
+
return () => {
|
|
86
|
+
history.pushState = originalPushState;
|
|
87
|
+
history.replaceState = originalReplaceState;
|
|
88
|
+
window.removeEventListener("popstate", sendPageview);
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/storage.ts
|
|
93
|
+
import { createMemoryStorage } from "@getdevteam/analytics-core";
|
|
94
|
+
function resolveLocalStorage() {
|
|
95
|
+
try {
|
|
96
|
+
if (typeof window === "undefined" || !window.localStorage) return void 0;
|
|
97
|
+
const probe = "__devteam_analytics_probe__";
|
|
98
|
+
window.localStorage.setItem(probe, "1");
|
|
99
|
+
window.localStorage.removeItem(probe);
|
|
100
|
+
return window.localStorage;
|
|
101
|
+
} catch {
|
|
102
|
+
return void 0;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function createBrowserStorage(resolve = resolveLocalStorage) {
|
|
106
|
+
const localStorage = resolve();
|
|
107
|
+
if (!localStorage) return createMemoryStorage();
|
|
108
|
+
return {
|
|
109
|
+
getItem: (key) => {
|
|
110
|
+
try {
|
|
111
|
+
return localStorage.getItem(key);
|
|
112
|
+
} catch {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
setItem: (key, value) => {
|
|
117
|
+
try {
|
|
118
|
+
localStorage.setItem(key, value);
|
|
119
|
+
} catch {
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
removeItem: (key) => {
|
|
123
|
+
try {
|
|
124
|
+
localStorage.removeItem(key);
|
|
125
|
+
} catch {
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// src/index.ts
|
|
132
|
+
var WEB_SDK_NAME = "@getdevteam/analytics-web";
|
|
133
|
+
var WEB_SDK_VERSION = "0.1.0";
|
|
134
|
+
function createAnalytics(config) {
|
|
135
|
+
let finalFlush = false;
|
|
136
|
+
const baseFetch = config.fetch ?? defaultBrowserFetch();
|
|
137
|
+
const client = createClient({
|
|
138
|
+
...config,
|
|
139
|
+
storage: config.storage ?? createBrowserStorage(),
|
|
140
|
+
fetch: (url, init) => {
|
|
141
|
+
if (finalFlush) return sendOnHide(url, init, config.key, baseFetch);
|
|
142
|
+
if (baseFetch) return baseFetch(url, init);
|
|
143
|
+
return Promise.reject(new Error("fetch is not available in this environment"));
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
client.setContext({
|
|
147
|
+
sdk_name: WEB_SDK_NAME,
|
|
148
|
+
sdk_version: WEB_SDK_VERSION,
|
|
149
|
+
...collectWebContext(),
|
|
150
|
+
...config.context
|
|
151
|
+
});
|
|
152
|
+
const teardowns = [];
|
|
153
|
+
if (typeof window !== "undefined") {
|
|
154
|
+
const flushOnHide = () => {
|
|
155
|
+
finalFlush = true;
|
|
156
|
+
void client.flush().finally(() => {
|
|
157
|
+
finalFlush = false;
|
|
158
|
+
});
|
|
159
|
+
};
|
|
160
|
+
const onPageHide = () => flushOnHide();
|
|
161
|
+
const onVisibilityChange = () => {
|
|
162
|
+
if (document.visibilityState === "hidden") flushOnHide();
|
|
163
|
+
};
|
|
164
|
+
window.addEventListener("pagehide", onPageHide);
|
|
165
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
166
|
+
teardowns.push(() => {
|
|
167
|
+
window.removeEventListener("pagehide", onPageHide);
|
|
168
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
169
|
+
});
|
|
170
|
+
if (config.autoCaptureErrors !== false) {
|
|
171
|
+
const onError = (event) => {
|
|
172
|
+
client.captureError(event.error ?? event.message, { source: "window.onerror" });
|
|
173
|
+
};
|
|
174
|
+
const onRejection = (event) => {
|
|
175
|
+
const reason = event.reason;
|
|
176
|
+
client.captureError(reason ?? "unhandled promise rejection", {
|
|
177
|
+
source: "unhandledrejection"
|
|
178
|
+
});
|
|
179
|
+
};
|
|
180
|
+
window.addEventListener("error", onError);
|
|
181
|
+
window.addEventListener("unhandledrejection", onRejection);
|
|
182
|
+
teardowns.push(() => {
|
|
183
|
+
window.removeEventListener("error", onError);
|
|
184
|
+
window.removeEventListener("unhandledrejection", onRejection);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
if (config.trackPageviews === true) {
|
|
188
|
+
teardowns.push(installPageviewTracking(client));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
...client,
|
|
193
|
+
shutdown: async () => {
|
|
194
|
+
for (const teardown of teardowns.splice(0)) {
|
|
195
|
+
teardown();
|
|
196
|
+
}
|
|
197
|
+
await client.shutdown();
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function defaultBrowserFetch() {
|
|
202
|
+
if (typeof fetch !== "function") return void 0;
|
|
203
|
+
return (url, init) => fetch(url, init);
|
|
204
|
+
}
|
|
205
|
+
function sendOnHide(url, init, key, baseFetch) {
|
|
206
|
+
if (baseFetch) {
|
|
207
|
+
return baseFetch(url, { ...init, keepalive: true });
|
|
208
|
+
}
|
|
209
|
+
if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
|
|
210
|
+
const beaconUrl = `${url}${url.includes("?") ? "&" : "?"}key=${encodeURIComponent(key)}`;
|
|
211
|
+
const delivered = navigator.sendBeacon(
|
|
212
|
+
beaconUrl,
|
|
213
|
+
new Blob([init.body], { type: "application/json" })
|
|
214
|
+
);
|
|
215
|
+
return Promise.resolve({ ok: delivered, status: delivered ? 202 : 503 });
|
|
216
|
+
}
|
|
217
|
+
return Promise.reject(new Error("no transport available for final flush"));
|
|
218
|
+
}
|
|
219
|
+
export {
|
|
220
|
+
WEB_SDK_NAME,
|
|
221
|
+
WEB_SDK_VERSION,
|
|
222
|
+
browserFromUserAgent,
|
|
223
|
+
collectWebContext,
|
|
224
|
+
createAnalytics,
|
|
225
|
+
createBrowserStorage,
|
|
226
|
+
currentPageProperties,
|
|
227
|
+
detectDeviceType,
|
|
228
|
+
installPageviewTracking,
|
|
229
|
+
osFromUserAgent
|
|
230
|
+
};
|
|
231
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/context.ts","../src/pageviews.ts","../src/storage.ts"],"sourcesContent":["import {\n createClient,\n type AnalyticsClient,\n type ClientConfig,\n type EventContext,\n type FetchLike,\n type FetchRequestInit,\n type FetchResponseLike,\n} from \"@getdevteam/analytics-core\";\nimport { collectWebContext } from \"./context\";\nimport { installPageviewTracking } from \"./pageviews\";\nimport { createBrowserStorage } from \"./storage\";\n\nexport const WEB_SDK_NAME = \"@getdevteam/analytics-web\";\nexport const WEB_SDK_VERSION = \"0.1.0\";\n\nexport interface WebAnalyticsConfig extends ClientConfig {\n autoCaptureErrors?: boolean;\n trackPageviews?: boolean;\n context?: Partial<EventContext>;\n}\n\nexport function createAnalytics(config: WebAnalyticsConfig): AnalyticsClient {\n let finalFlush = false;\n const baseFetch = config.fetch ?? defaultBrowserFetch();\n\n const client = createClient({\n ...config,\n storage: config.storage ?? createBrowserStorage(),\n fetch: (url, init) => {\n if (finalFlush) return sendOnHide(url, init, config.key, baseFetch);\n if (baseFetch) return baseFetch(url, init);\n return Promise.reject(new Error(\"fetch is not available in this environment\"));\n },\n });\n\n client.setContext({\n sdk_name: WEB_SDK_NAME,\n sdk_version: WEB_SDK_VERSION,\n ...collectWebContext(),\n ...config.context,\n });\n\n const teardowns: Array<() => void> = [];\n\n if (typeof window !== \"undefined\") {\n const flushOnHide = (): void => {\n finalFlush = true;\n void client.flush().finally(() => {\n finalFlush = false;\n });\n };\n const onPageHide = (): void => flushOnHide();\n const onVisibilityChange = (): void => {\n if (document.visibilityState === \"hidden\") flushOnHide();\n };\n window.addEventListener(\"pagehide\", onPageHide);\n document.addEventListener(\"visibilitychange\", onVisibilityChange);\n teardowns.push(() => {\n window.removeEventListener(\"pagehide\", onPageHide);\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n });\n\n if (config.autoCaptureErrors !== false) {\n const onError = (event: ErrorEvent): void => {\n client.captureError(event.error ?? event.message, { source: \"window.onerror\" });\n };\n const onRejection = (event: Event): void => {\n const reason = (event as { reason?: unknown }).reason;\n client.captureError(reason ?? \"unhandled promise rejection\", {\n source: \"unhandledrejection\",\n });\n };\n window.addEventListener(\"error\", onError);\n window.addEventListener(\"unhandledrejection\", onRejection);\n teardowns.push(() => {\n window.removeEventListener(\"error\", onError);\n window.removeEventListener(\"unhandledrejection\", onRejection);\n });\n }\n\n if (config.trackPageviews === true) {\n teardowns.push(installPageviewTracking(client));\n }\n }\n\n return {\n ...client,\n shutdown: async () => {\n for (const teardown of teardowns.splice(0)) {\n teardown();\n }\n await client.shutdown();\n },\n };\n}\n\nfunction defaultBrowserFetch(): FetchLike | undefined {\n if (typeof fetch !== \"function\") return undefined;\n return (url, init) => fetch(url, init);\n}\n\nfunction sendOnHide(\n url: string,\n init: FetchRequestInit,\n key: string,\n baseFetch: FetchLike | undefined,\n): Promise<FetchResponseLike> {\n if (baseFetch) {\n return baseFetch(url, { ...init, keepalive: true });\n }\n if (typeof navigator !== \"undefined\" && typeof navigator.sendBeacon === \"function\") {\n // sendBeacon cannot set headers, so the key rides as a query parameter as a last resort.\n const beaconUrl = `${url}${url.includes(\"?\") ? \"&\" : \"?\"}key=${encodeURIComponent(key)}`;\n const delivered = navigator.sendBeacon(\n beaconUrl,\n new Blob([init.body], { type: \"application/json\" }),\n );\n return Promise.resolve({ ok: delivered, status: delivered ? 202 : 503 });\n }\n return Promise.reject(new Error(\"no transport available for final flush\"));\n}\n\nexport { collectWebContext, browserFromUserAgent, osFromUserAgent, detectDeviceType } from \"./context\";\nexport { createBrowserStorage } from \"./storage\";\nexport { currentPageProperties, installPageviewTracking } from \"./pageviews\";\nexport type {\n AnalyticsClient,\n AnalyticsLogger,\n ClientConfig,\n EventContext,\n FetchLike,\n LogSeverity,\n Properties,\n StorageAdapter,\n} from \"@getdevteam/analytics-core\";\n","import type { EventContext } from \"@getdevteam/analytics-core\";\n\nexport function browserFromUserAgent(ua: string): string | undefined {\n if (/Edg(e|A|iOS)?\\//.test(ua)) return \"Edge\";\n if (/Firefox\\/|FxiOS\\//.test(ua)) return \"Firefox\";\n if (/CriOS\\/|Chrome\\//.test(ua)) return \"Chrome\";\n if (/Safari\\//.test(ua)) return \"Safari\";\n return undefined;\n}\n\nexport function osFromUserAgent(\n ua: string,\n platform?: string,\n): { os_name?: string; os_version?: string } {\n if (/Windows/.test(ua)) {\n const match = /Windows NT ([\\d.]+)/.exec(ua);\n return { os_name: \"Windows\", ...(match?.[1] ? { os_version: match[1] } : {}) };\n }\n if (/iPhone|iPad|iPod/.test(ua)) {\n const match = /OS (\\d+[_.]\\d+(?:[_.]\\d+)?)/.exec(ua);\n return { os_name: \"iOS\", ...(match?.[1] ? { os_version: match[1].replace(/_/g, \".\") } : {}) };\n }\n if (/Android/.test(ua)) {\n const match = /Android ([\\d.]+)/.exec(ua);\n return { os_name: \"Android\", ...(match?.[1] ? { os_version: match[1] } : {}) };\n }\n if (/Mac OS X|Macintosh/.test(ua) || (platform ?? \"\").startsWith(\"Mac\")) {\n const match = /Mac OS X (\\d+[_.]\\d+(?:[_.]\\d+)?)/.exec(ua);\n return { os_name: \"macOS\", ...(match?.[1] ? { os_version: match[1].replace(/_/g, \".\") } : {}) };\n }\n if (/Linux/.test(ua) || (platform ?? \"\").startsWith(\"Linux\")) {\n return { os_name: \"Linux\" };\n }\n return {};\n}\n\ninterface WindowLike {\n matchMedia?: (query: string) => { matches: boolean };\n innerWidth?: number;\n screen?: { width?: number };\n}\n\nexport function detectDeviceType(win: WindowLike): string {\n try {\n const coarse =\n typeof win.matchMedia === \"function\" && win.matchMedia(\"(pointer: coarse)\").matches;\n if (!coarse) return \"desktop\";\n const width = win.innerWidth || win.screen?.width || 0;\n return width >= 768 ? \"tablet\" : \"mobile\";\n } catch {\n return \"desktop\";\n }\n}\n\nexport function collectWebContext(): EventContext {\n if (typeof window === \"undefined\" || typeof navigator === \"undefined\") {\n return { platform: \"web\" };\n }\n const ua = navigator.userAgent ?? \"\";\n const context: EventContext = { platform: \"web\" };\n const browser = browserFromUserAgent(ua);\n if (browser !== undefined) context.browser = browser;\n Object.assign(context, osFromUserAgent(ua, navigator.platform));\n context.device_type = detectDeviceType(window);\n if (navigator.language) context.locale = navigator.language;\n if (window.screen) {\n context.screen = { w: window.screen.width ?? 0, h: window.screen.height ?? 0 };\n }\n return context;\n}\n","import type { AnalyticsClient, Properties } from \"@getdevteam/analytics-core\";\n\nexport function currentPageProperties(): Properties {\n return {\n url: window.location.href,\n title: document.title,\n };\n}\n\nexport function installPageviewTracking(client: AnalyticsClient): () => void {\n const sendPageview = (): void => client.page(currentPageProperties());\n const history = window.history;\n const originalPushState = history.pushState.bind(history);\n const originalReplaceState = history.replaceState.bind(history);\n\n history.pushState = (...args: Parameters<History[\"pushState\"]>) => {\n originalPushState(...args);\n sendPageview();\n };\n history.replaceState = (...args: Parameters<History[\"replaceState\"]>) => {\n originalReplaceState(...args);\n sendPageview();\n };\n window.addEventListener(\"popstate\", sendPageview);\n sendPageview();\n\n return () => {\n history.pushState = originalPushState;\n history.replaceState = originalReplaceState;\n window.removeEventListener(\"popstate\", sendPageview);\n };\n}\n","import { createMemoryStorage, type StorageAdapter } from \"@getdevteam/analytics-core\";\n\nexport function resolveLocalStorage(): Storage | undefined {\n try {\n if (typeof window === \"undefined\" || !window.localStorage) return undefined;\n const probe = \"__devteam_analytics_probe__\";\n window.localStorage.setItem(probe, \"1\");\n window.localStorage.removeItem(probe);\n return window.localStorage;\n } catch {\n return undefined;\n }\n}\n\nexport function createBrowserStorage(\n resolve: () => Storage | undefined = resolveLocalStorage,\n): StorageAdapter {\n const localStorage = resolve();\n if (!localStorage) return createMemoryStorage();\n return {\n getItem: (key) => {\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n },\n setItem: (key, value) => {\n try {\n localStorage.setItem(key, value);\n } catch {\n // quota or private-mode failure; queue persistence degrades gracefully\n }\n },\n removeItem: (key) => {\n try {\n localStorage.removeItem(key);\n } catch {\n // ignore\n }\n },\n };\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@getdevteam/analytics-web",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Browser SDK for the DevTeam analytics and logging platform.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/getdevteam-ai/analytics",
|
|
9
|
+
"directory": "src/sdk/packages/web"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "./dist/index.cjs",
|
|
13
|
+
"module": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"import": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"default": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"require": {
|
|
22
|
+
"types": "./dist/index.d.cts",
|
|
23
|
+
"default": "./dist/index.cjs"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": ["dist"],
|
|
28
|
+
"sideEffects": false,
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsup",
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"typecheck": "tsc --noEmit"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@getdevteam/analytics-core": "0.1.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"jsdom": "^26.1.0",
|
|
42
|
+
"tsup": "^8.5.0",
|
|
43
|
+
"typescript": "^5.8.3",
|
|
44
|
+
"vitest": "^3.2.4"
|
|
45
|
+
}
|
|
46
|
+
}
|