onerway-analytics 1.0.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/bundle/index.js +1361 -0
- package/dist/bundle/index.js.map +7 -0
- package/dist/core/analytics.d.ts +45 -0
- package/dist/core/analytics.d.ts.map +1 -0
- package/dist/core/analytics.js +369 -0
- package/dist/core/analytics.test.d.ts +2 -0
- package/dist/core/analytics.test.d.ts.map +1 -0
- package/dist/core/analytics.test.js +169 -0
- package/dist/core/auto-track.d.ts +6 -0
- package/dist/core/auto-track.d.ts.map +1 -0
- package/dist/core/auto-track.js +126 -0
- package/dist/core/context-collector.d.ts +4 -0
- package/dist/core/context-collector.d.ts.map +1 -0
- package/dist/core/context-collector.js +42 -0
- package/dist/core/error-monitor.d.ts +5 -0
- package/dist/core/error-monitor.d.ts.map +1 -0
- package/dist/core/error-monitor.js +61 -0
- package/dist/core/ga-adapter.d.ts +12 -0
- package/dist/core/ga-adapter.d.ts.map +1 -0
- package/dist/core/ga-adapter.js +35 -0
- package/dist/core/ga-loader.d.ts +10 -0
- package/dist/core/ga-loader.d.ts.map +1 -0
- package/dist/core/ga-loader.js +30 -0
- package/dist/core/ga-manager.d.ts +24 -0
- package/dist/core/ga-manager.d.ts.map +1 -0
- package/dist/core/ga-manager.js +64 -0
- package/dist/core/performance-monitor.d.ts +5 -0
- package/dist/core/performance-monitor.d.ts.map +1 -0
- package/dist/core/performance-monitor.js +43 -0
- package/dist/core/sender.d.ts +10 -0
- package/dist/core/sender.d.ts.map +1 -0
- package/dist/core/sender.js +65 -0
- package/dist/core/session-manager.d.ts +13 -0
- package/dist/core/session-manager.d.ts.map +1 -0
- package/dist/core/session-manager.js +54 -0
- package/dist/core/storage.d.ts +9 -0
- package/dist/core/storage.d.ts.map +1 -0
- package/dist/core/storage.js +48 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/types/index.d.ts +162 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +28 -0
- package/dist/utils/index.d.ts +30 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +216 -0
- package/package.json +47 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { onLCP, onFCP, onCLS, onINP, onTTFB, } from 'web-vitals';
|
|
2
|
+
function normalize(value, isCLS) {
|
|
3
|
+
if (isCLS) {
|
|
4
|
+
return Math.round(value * 10000) / 10000;
|
|
5
|
+
}
|
|
6
|
+
return Math.round(value);
|
|
7
|
+
}
|
|
8
|
+
function reportMetric(api, metric) {
|
|
9
|
+
const isCLS = metric.name === 'CLS';
|
|
10
|
+
const properties = {
|
|
11
|
+
action: 'metric',
|
|
12
|
+
target_type: 'performance',
|
|
13
|
+
metric_name: metric.name,
|
|
14
|
+
metric_value: normalize(metric.value, isCLS),
|
|
15
|
+
metric_rating: metric.rating,
|
|
16
|
+
delta: normalize(metric.delta, isCLS),
|
|
17
|
+
metric_id: metric.id,
|
|
18
|
+
navigation_type: metric.navigationType,
|
|
19
|
+
};
|
|
20
|
+
if (metric.name === 'LCP') {
|
|
21
|
+
const entry = metric.entries[metric.entries.length - 1];
|
|
22
|
+
if (entry) {
|
|
23
|
+
properties.lcp_element = entry.element?.tagName?.toLowerCase() || '';
|
|
24
|
+
properties.lcp_url = entry.url || '';
|
|
25
|
+
properties.lcp_size = entry.size;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
api.track('web_vital', properties);
|
|
29
|
+
}
|
|
30
|
+
export function initPerformanceMonitor(api, config = {}) {
|
|
31
|
+
if (config.enabled === false)
|
|
32
|
+
return;
|
|
33
|
+
try {
|
|
34
|
+
onLCP((metric) => reportMetric(api, metric));
|
|
35
|
+
onFCP((metric) => reportMetric(api, metric));
|
|
36
|
+
onCLS((metric) => reportMetric(api, metric));
|
|
37
|
+
onINP((metric) => reportMetric(api, metric));
|
|
38
|
+
onTTFB((metric) => reportMetric(api, metric));
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Web Vitals API not supported in this browser
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AnalyticsPayload } from '../types';
|
|
2
|
+
export declare class Sender {
|
|
3
|
+
static send(payload: AnalyticsPayload, serverUrl: string, apiKey: string): Promise<void>;
|
|
4
|
+
static sendBeacon(payload: AnalyticsPayload, serverUrl: string, apiKey: string): Promise<void>;
|
|
5
|
+
static fetchSend(payload: AnalyticsPayload, serverUrl: string, apiKey: string): Promise<void>;
|
|
6
|
+
static xhrSend(payload: AnalyticsPayload, serverUrl: string, apiKey: string): Promise<void>;
|
|
7
|
+
private static supportsKeepalive;
|
|
8
|
+
private static buildBeaconUrl;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=sender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sender.d.ts","sourceRoot":"","sources":["../../src/core/sender.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,qBAAa,MAAM;WACJ,IAAI,CAAC,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;WAOjF,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;WAcvF,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;WAgBtF,OAAO,CAAC,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBjG,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAQhC,OAAO,CAAC,MAAM,CAAC,cAAc;CAI9B"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export class Sender {
|
|
2
|
+
static async send(payload, serverUrl, apiKey) {
|
|
3
|
+
if (Sender.supportsKeepalive()) {
|
|
4
|
+
return Sender.fetchSend(payload, serverUrl, apiKey);
|
|
5
|
+
}
|
|
6
|
+
return Sender.xhrSend(payload, serverUrl, apiKey);
|
|
7
|
+
}
|
|
8
|
+
static async sendBeacon(payload, serverUrl, apiKey) {
|
|
9
|
+
if (typeof navigator === 'undefined' || !navigator.sendBeacon) {
|
|
10
|
+
throw new Error('sendBeacon not available');
|
|
11
|
+
}
|
|
12
|
+
const url = Sender.buildBeaconUrl(serverUrl, apiKey);
|
|
13
|
+
const blob = new Blob([JSON.stringify(payload)], { type: 'application/json' });
|
|
14
|
+
const success = navigator.sendBeacon(url, blob);
|
|
15
|
+
if (!success) {
|
|
16
|
+
throw new Error('sendBeacon rejected payload');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
static async fetchSend(payload, serverUrl, apiKey) {
|
|
20
|
+
const response = await fetch(serverUrl, {
|
|
21
|
+
method: 'POST',
|
|
22
|
+
headers: {
|
|
23
|
+
'Content-Type': 'application/json',
|
|
24
|
+
apiKey,
|
|
25
|
+
},
|
|
26
|
+
body: JSON.stringify(payload),
|
|
27
|
+
keepalive: true,
|
|
28
|
+
});
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
static async xhrSend(payload, serverUrl, apiKey) {
|
|
34
|
+
return new Promise((resolve, reject) => {
|
|
35
|
+
const xhr = new XMLHttpRequest();
|
|
36
|
+
xhr.open('POST', serverUrl);
|
|
37
|
+
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
38
|
+
xhr.setRequestHeader('apiKey', apiKey);
|
|
39
|
+
xhr.timeout = 10000;
|
|
40
|
+
xhr.onload = () => {
|
|
41
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
42
|
+
resolve();
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
reject(new Error(`HTTP ${xhr.status}: ${xhr.statusText}`));
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
xhr.onerror = () => reject(new Error('XHR network error'));
|
|
49
|
+
xhr.ontimeout = () => reject(new Error('XHR timeout'));
|
|
50
|
+
xhr.send(JSON.stringify(payload));
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
static supportsKeepalive() {
|
|
54
|
+
try {
|
|
55
|
+
return typeof Request !== 'undefined' && 'keepalive' in Request.prototype;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
static buildBeaconUrl(serverUrl, apiKey) {
|
|
62
|
+
const separator = serverUrl.includes('?') ? '&' : '?';
|
|
63
|
+
return `${serverUrl}${separator}apiKey=${encodeURIComponent(apiKey)}`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class SessionManager {
|
|
2
|
+
private sessionId;
|
|
3
|
+
private createdAt;
|
|
4
|
+
private timeout;
|
|
5
|
+
constructor(timeout?: number);
|
|
6
|
+
getSessionId(): string;
|
|
7
|
+
refresh(): void;
|
|
8
|
+
private loadSession;
|
|
9
|
+
private saveSession;
|
|
10
|
+
private isExpired;
|
|
11
|
+
private createNewSession;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=session-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/core/session-manager.ts"],"names":[],"mappings":"AAUA,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,MAAgC;IAYrD,YAAY,IAAI,MAAM;IAOtB,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,gBAAgB;CAMzB"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { generateUUID, safeSessionStorageGet, safeSessionStorageSet } from '../utils';
|
|
2
|
+
const SESSION_KEY = '__analytics_session__';
|
|
3
|
+
const SESSION_DEFAULT_TIMEOUT = 30 * 60 * 1000;
|
|
4
|
+
export class SessionManager {
|
|
5
|
+
constructor(timeout = SESSION_DEFAULT_TIMEOUT) {
|
|
6
|
+
this.createdAt = 0;
|
|
7
|
+
this.timeout = timeout;
|
|
8
|
+
const existing = this.loadSession();
|
|
9
|
+
if (existing && !this.isExpired(existing)) {
|
|
10
|
+
this.sessionId = existing.sessionId;
|
|
11
|
+
this.createdAt = existing.createdAt;
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
this.sessionId = this.createNewSession();
|
|
15
|
+
this.createdAt = Date.now();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
getSessionId() {
|
|
19
|
+
if (this.isExpired({ sessionId: this.sessionId, createdAt: this.createdAt })) {
|
|
20
|
+
this.sessionId = this.createNewSession();
|
|
21
|
+
}
|
|
22
|
+
return this.sessionId;
|
|
23
|
+
}
|
|
24
|
+
refresh() {
|
|
25
|
+
this.sessionId = this.createNewSession();
|
|
26
|
+
}
|
|
27
|
+
loadSession() {
|
|
28
|
+
try {
|
|
29
|
+
const raw = safeSessionStorageGet(SESSION_KEY);
|
|
30
|
+
if (!raw)
|
|
31
|
+
return null;
|
|
32
|
+
return JSON.parse(raw);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
saveSession() {
|
|
39
|
+
const data = {
|
|
40
|
+
sessionId: this.sessionId,
|
|
41
|
+
createdAt: this.createdAt,
|
|
42
|
+
};
|
|
43
|
+
safeSessionStorageSet(SESSION_KEY, JSON.stringify(data));
|
|
44
|
+
}
|
|
45
|
+
isExpired(data) {
|
|
46
|
+
return Date.now() - data.createdAt > this.timeout;
|
|
47
|
+
}
|
|
48
|
+
createNewSession() {
|
|
49
|
+
const id = generateUUID();
|
|
50
|
+
this.createdAt = Date.now();
|
|
51
|
+
this.saveSession();
|
|
52
|
+
return id;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { EventPayload } from '../types';
|
|
2
|
+
export declare class StorageQueue {
|
|
3
|
+
static enqueue(event: EventPayload): void;
|
|
4
|
+
static recover(): EventPayload[];
|
|
5
|
+
static clear(): void;
|
|
6
|
+
static getQueueSize(): number;
|
|
7
|
+
private static readQueue;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/core/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAqD,MAAM,UAAU,CAAC;AAG3F,qBAAa,YAAY;IACvB,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAezC,MAAM,CAAC,OAAO,IAAI,YAAY,EAAE;IAYhC,MAAM,CAAC,KAAK,IAAI,IAAI;IAIpB,MAAM,CAAC,YAAY,IAAI,MAAM;IAI7B,OAAO,CAAC,MAAM,CAAC,SAAS;CAWzB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { STORAGE_KEYS, MAX_STORAGE_ITEMS } from '../types';
|
|
2
|
+
import { safeLocalStorageGet, safeLocalStorageSet, safeLocalStorageRemove } from '../utils';
|
|
3
|
+
export class StorageQueue {
|
|
4
|
+
static enqueue(event) {
|
|
5
|
+
try {
|
|
6
|
+
const queue = StorageQueue.readQueue();
|
|
7
|
+
queue.push({ event, storedAt: Date.now() });
|
|
8
|
+
while (queue.length > MAX_STORAGE_ITEMS) {
|
|
9
|
+
queue.shift();
|
|
10
|
+
}
|
|
11
|
+
safeLocalStorageSet(STORAGE_KEYS.FAILED_QUEUE, JSON.stringify(queue));
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
// Silently fail if storage is unavailable
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
static recover() {
|
|
18
|
+
try {
|
|
19
|
+
const queue = StorageQueue.readQueue();
|
|
20
|
+
StorageQueue.clear();
|
|
21
|
+
const events = queue.map((item) => item.event);
|
|
22
|
+
return events;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
static clear() {
|
|
29
|
+
safeLocalStorageRemove(STORAGE_KEYS.FAILED_QUEUE);
|
|
30
|
+
}
|
|
31
|
+
static getQueueSize() {
|
|
32
|
+
return StorageQueue.readQueue().length;
|
|
33
|
+
}
|
|
34
|
+
static readQueue() {
|
|
35
|
+
try {
|
|
36
|
+
const raw = safeLocalStorageGet(STORAGE_KEYS.FAILED_QUEUE);
|
|
37
|
+
if (!raw)
|
|
38
|
+
return [];
|
|
39
|
+
const parsed = JSON.parse(raw);
|
|
40
|
+
if (!Array.isArray(parsed))
|
|
41
|
+
return [];
|
|
42
|
+
return parsed;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { Analytics, createAnalytics } from './core/analytics';
|
|
2
|
+
export { Sender } from './core/sender';
|
|
3
|
+
export { StorageQueue } from './core/storage';
|
|
4
|
+
export { SessionManager } from './core/session-manager';
|
|
5
|
+
export { initAutoTrack } from './core/auto-track';
|
|
6
|
+
export type { AutoTrackAPI } from './core/auto-track';
|
|
7
|
+
export { initErrorMonitor } from './core/error-monitor';
|
|
8
|
+
export type { ErrorMonitorAPI } from './core/error-monitor';
|
|
9
|
+
export { GAManager } from './core/ga-manager';
|
|
10
|
+
export { initPerformanceMonitor } from './core/performance-monitor';
|
|
11
|
+
export type { PerformanceMonitorAPI } from './core/performance-monitor';
|
|
12
|
+
export { collectContext, collectMarketing } from './core/context-collector';
|
|
13
|
+
export type { AnalyticsConfig, AnalyticsPayload, EventPayload, EventProperties, EventContext, ContextPayload, MarketingPayload, BrowserInfo, OSInfo, TrackOptions, TrackEvent, QueueItem, UserProfile, Environment, PerformanceConfig, GAConfig, GAConsentMode, GAConsentParams, } from './types';
|
|
14
|
+
export { API_KEY_MAP, SDK_VERSION, DEFAULT_CONFIG, STORAGE_KEYS, } from './types';
|
|
15
|
+
export { generateUUID, generateId, getTimestamp, isObject, merge, detectBrowser, detectOS, getDeviceType, getScreenSize, getPageUrl, getReferrer, getHostname, getTimezone, getLanguage, getCountryFromLanguage, parseUTMParams, isBrowser, truncateText, } from './utils';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,YAAY,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5E,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,MAAM,EACN,YAAY,EACZ,UAAU,EACV,SAAS,EACT,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,QAAQ,EACR,aAAa,EACb,eAAe,GAChB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,WAAW,EACX,WAAW,EACX,cAAc,EACd,YAAY,GACb,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,KAAK,EACL,aAAa,EACb,QAAQ,EACR,aAAa,EACb,aAAa,EACb,UAAU,EACV,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,sBAAsB,EACtB,cAAc,EACd,SAAS,EACT,YAAY,GACb,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { Analytics, createAnalytics } from './core/analytics';
|
|
2
|
+
export { Sender } from './core/sender';
|
|
3
|
+
export { StorageQueue } from './core/storage';
|
|
4
|
+
export { SessionManager } from './core/session-manager';
|
|
5
|
+
export { initAutoTrack } from './core/auto-track';
|
|
6
|
+
export { initErrorMonitor } from './core/error-monitor';
|
|
7
|
+
export { GAManager } from './core/ga-manager';
|
|
8
|
+
export { initPerformanceMonitor } from './core/performance-monitor';
|
|
9
|
+
export { collectContext, collectMarketing } from './core/context-collector';
|
|
10
|
+
export { API_KEY_MAP, SDK_VERSION, DEFAULT_CONFIG, STORAGE_KEYS, } from './types';
|
|
11
|
+
export { generateUUID, generateId, getTimestamp, isObject, merge, detectBrowser, detectOS, getDeviceType, getScreenSize, getPageUrl, getReferrer, getHostname, getTimezone, getLanguage, getCountryFromLanguage, parseUTMParams, isBrowser, truncateText, } from './utils';
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
export type Environment = 'beta' | 'development' | 'test' | 'testing' | 'sit' | 'uat' | 'prod' | 'production';
|
|
2
|
+
export interface BrowserInfo {
|
|
3
|
+
name: string;
|
|
4
|
+
version: string;
|
|
5
|
+
}
|
|
6
|
+
export interface OSInfo {
|
|
7
|
+
name: string;
|
|
8
|
+
version: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ContextPayload {
|
|
11
|
+
sdk_version: string;
|
|
12
|
+
app_key: string;
|
|
13
|
+
screen_width: number;
|
|
14
|
+
screen_height: number;
|
|
15
|
+
user_agent: string;
|
|
16
|
+
referrer: string;
|
|
17
|
+
hostname: string;
|
|
18
|
+
browser: BrowserInfo;
|
|
19
|
+
operating_system: OSInfo;
|
|
20
|
+
device_type: 'mobile' | 'tablet' | 'desktop';
|
|
21
|
+
country: string;
|
|
22
|
+
language: string;
|
|
23
|
+
merchant_language: string;
|
|
24
|
+
timezone: string;
|
|
25
|
+
client_type: string;
|
|
26
|
+
}
|
|
27
|
+
export interface MarketingPayload {
|
|
28
|
+
utm_source?: string;
|
|
29
|
+
utm_medium?: string;
|
|
30
|
+
utm_campaign?: string;
|
|
31
|
+
utm_term?: string;
|
|
32
|
+
utm_content?: string;
|
|
33
|
+
landing_page?: string;
|
|
34
|
+
referrer_url?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface EventProperties {
|
|
37
|
+
system?: string;
|
|
38
|
+
domain?: string;
|
|
39
|
+
scene?: string;
|
|
40
|
+
action?: string;
|
|
41
|
+
target_type?: string;
|
|
42
|
+
target_id?: string;
|
|
43
|
+
page_url?: string;
|
|
44
|
+
flow_id?: string;
|
|
45
|
+
entity_type?: string;
|
|
46
|
+
entity_id?: string;
|
|
47
|
+
status?: string;
|
|
48
|
+
response_code?: string;
|
|
49
|
+
response_msg?: string;
|
|
50
|
+
duration_ms?: number;
|
|
51
|
+
request_id?: string;
|
|
52
|
+
[key: string]: unknown;
|
|
53
|
+
}
|
|
54
|
+
export interface EventContext {
|
|
55
|
+
[key: string]: unknown;
|
|
56
|
+
}
|
|
57
|
+
export interface EventPayload {
|
|
58
|
+
event_id: string;
|
|
59
|
+
event_name: string;
|
|
60
|
+
batch_event_index: number;
|
|
61
|
+
batch_ordering_id: string;
|
|
62
|
+
batch_page_id: string;
|
|
63
|
+
timestamp: number;
|
|
64
|
+
key_event: boolean;
|
|
65
|
+
event_properties: EventProperties;
|
|
66
|
+
context?: EventContext;
|
|
67
|
+
}
|
|
68
|
+
export interface AnalyticsPayload {
|
|
69
|
+
client_id: string;
|
|
70
|
+
user_id?: string;
|
|
71
|
+
session_id: string;
|
|
72
|
+
user_properties?: Record<string, unknown>;
|
|
73
|
+
context: ContextPayload;
|
|
74
|
+
marketing: MarketingPayload;
|
|
75
|
+
events: EventPayload[];
|
|
76
|
+
}
|
|
77
|
+
export interface PerformanceConfig {
|
|
78
|
+
enabled?: boolean;
|
|
79
|
+
}
|
|
80
|
+
export type GAConsentMode = 'default' | 'update';
|
|
81
|
+
export interface GAConsentParams {
|
|
82
|
+
ad_storage?: 'granted' | 'denied';
|
|
83
|
+
analytics_storage?: 'granted' | 'denied';
|
|
84
|
+
ad_user_data?: 'granted' | 'denied';
|
|
85
|
+
ad_personalization?: 'granted' | 'denied';
|
|
86
|
+
[key: string]: unknown;
|
|
87
|
+
}
|
|
88
|
+
export interface GAConfig {
|
|
89
|
+
measurementId: string;
|
|
90
|
+
enabled: boolean;
|
|
91
|
+
sendPageView?: boolean;
|
|
92
|
+
debugMode?: boolean;
|
|
93
|
+
}
|
|
94
|
+
export interface AnalyticsConfig {
|
|
95
|
+
appKey?: string;
|
|
96
|
+
serverUrl: string;
|
|
97
|
+
apiKey?: string;
|
|
98
|
+
env?: Environment;
|
|
99
|
+
debug?: boolean;
|
|
100
|
+
autoTrack?: boolean;
|
|
101
|
+
system?: string;
|
|
102
|
+
domain?: string;
|
|
103
|
+
keyEvents?: string[];
|
|
104
|
+
bufferFlushInterval?: number;
|
|
105
|
+
bufferMaxSize?: number;
|
|
106
|
+
maxRetryCount?: number;
|
|
107
|
+
sessionTimeout?: number;
|
|
108
|
+
autoTrackSelector?: string;
|
|
109
|
+
performance?: PerformanceConfig;
|
|
110
|
+
ga?: GAConfig;
|
|
111
|
+
/** @deprecated use appKey instead */
|
|
112
|
+
appId?: string;
|
|
113
|
+
}
|
|
114
|
+
export interface TrackOptions {
|
|
115
|
+
keyEvent?: boolean;
|
|
116
|
+
}
|
|
117
|
+
export interface UserProfile {
|
|
118
|
+
userId?: string;
|
|
119
|
+
anonymousId?: string;
|
|
120
|
+
attributes?: Record<string, unknown>;
|
|
121
|
+
}
|
|
122
|
+
/** @deprecated use EventPayload instead */
|
|
123
|
+
export interface TrackEvent {
|
|
124
|
+
event: string;
|
|
125
|
+
properties?: Record<string, unknown>;
|
|
126
|
+
timestamp?: number;
|
|
127
|
+
}
|
|
128
|
+
/** @deprecated use AnalyticsPayload instead */
|
|
129
|
+
export interface QueueItem {
|
|
130
|
+
id: string;
|
|
131
|
+
event: TrackEvent;
|
|
132
|
+
retryCount: number;
|
|
133
|
+
}
|
|
134
|
+
export interface StorageQueueItem {
|
|
135
|
+
event: EventPayload;
|
|
136
|
+
storedAt: number;
|
|
137
|
+
}
|
|
138
|
+
export interface RetryEntry {
|
|
139
|
+
events: EventPayload[];
|
|
140
|
+
retryCount: number;
|
|
141
|
+
timer: ReturnType<typeof setTimeout> | null;
|
|
142
|
+
}
|
|
143
|
+
export declare const API_KEY_MAP: Record<string, string>;
|
|
144
|
+
export declare const SDK_VERSION = "1.0.0";
|
|
145
|
+
export declare const DEFAULT_CONFIG: {
|
|
146
|
+
readonly debug: false;
|
|
147
|
+
readonly autoTrack: true;
|
|
148
|
+
readonly bufferFlushInterval: 5000;
|
|
149
|
+
readonly bufferMaxSize: 25;
|
|
150
|
+
readonly maxRetryCount: 3;
|
|
151
|
+
readonly sessionTimeout: number;
|
|
152
|
+
readonly clientType: "WEB";
|
|
153
|
+
readonly merchantLanguage: "en";
|
|
154
|
+
};
|
|
155
|
+
export declare const STORAGE_KEYS: {
|
|
156
|
+
readonly FAILED_QUEUE: "__analytics_failed_queue__";
|
|
157
|
+
readonly CLIENT_ID: "__analytics_client_id__";
|
|
158
|
+
readonly LANDING_PAGE: "__analytics_landing_page__";
|
|
159
|
+
readonly REFERRER_URL: "__analytics_referrer_url__";
|
|
160
|
+
};
|
|
161
|
+
export declare const MAX_STORAGE_ITEMS = 500;
|
|
162
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export const API_KEY_MAP = {
|
|
2
|
+
beta: '5skbadERCne5HKSS9a1EXz5RetUiEfpP',
|
|
3
|
+
development: '5skbadERCne5HKSS9a1EXz5RetUiEfpP',
|
|
4
|
+
test: 'Dguh5yxNDEwyQlqDmikmd7ImruaOp8c8',
|
|
5
|
+
testing: 'Dguh5yxNDEwyQlqDmikmd7ImruaOp8c8',
|
|
6
|
+
sit: 'Dguh5yxNDEwyQlqDmikmd7ImruaOp8c8',
|
|
7
|
+
uat: 'W565QolX6clTuL1Kqgpp0JmUqBkWKY6i',
|
|
8
|
+
prod: 'HUk5Kogyuv9zH5qDA2qSCjVEnhanSkf8',
|
|
9
|
+
production: 'HUk5Kogyuv9zH5qDA2qSCjVEnhanSkf8',
|
|
10
|
+
};
|
|
11
|
+
export const SDK_VERSION = '1.0.0';
|
|
12
|
+
export const DEFAULT_CONFIG = {
|
|
13
|
+
debug: false,
|
|
14
|
+
autoTrack: true,
|
|
15
|
+
bufferFlushInterval: 5000,
|
|
16
|
+
bufferMaxSize: 25,
|
|
17
|
+
maxRetryCount: 3,
|
|
18
|
+
sessionTimeout: 30 * 60 * 1000,
|
|
19
|
+
clientType: 'WEB',
|
|
20
|
+
merchantLanguage: 'en',
|
|
21
|
+
};
|
|
22
|
+
export const STORAGE_KEYS = {
|
|
23
|
+
FAILED_QUEUE: '__analytics_failed_queue__',
|
|
24
|
+
CLIENT_ID: '__analytics_client_id__',
|
|
25
|
+
LANDING_PAGE: '__analytics_landing_page__',
|
|
26
|
+
REFERRER_URL: '__analytics_referrer_url__',
|
|
27
|
+
};
|
|
28
|
+
export const MAX_STORAGE_ITEMS = 500;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { BrowserInfo, OSInfo } from '../types';
|
|
2
|
+
export declare function generateId(): string;
|
|
3
|
+
export declare function getTimestamp(): number;
|
|
4
|
+
export declare function isObject(value: unknown): value is Record<string, unknown>;
|
|
5
|
+
export declare function merge<T extends Record<string, unknown>>(target: T, source: Partial<T>): T;
|
|
6
|
+
export declare function generateUUID(): string;
|
|
7
|
+
export declare function generateShortId(): string;
|
|
8
|
+
export declare function detectBrowser(): BrowserInfo;
|
|
9
|
+
export declare function detectOS(): OSInfo;
|
|
10
|
+
export declare function getDeviceType(): 'mobile' | 'tablet' | 'desktop';
|
|
11
|
+
export declare function getScreenSize(): {
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
};
|
|
15
|
+
export declare function getPageUrl(): string;
|
|
16
|
+
export declare function getReferrer(): string;
|
|
17
|
+
export declare function getHostname(): string;
|
|
18
|
+
export declare function getTimezone(): string;
|
|
19
|
+
export declare function getLanguage(): string;
|
|
20
|
+
export declare function getCountryFromLanguage(language: string): string;
|
|
21
|
+
export declare function parseUTMParams(): Record<string, string>;
|
|
22
|
+
export declare function isBrowser(): boolean;
|
|
23
|
+
export declare function safeLocalStorageGet(key: string): string | null;
|
|
24
|
+
export declare function safeLocalStorageSet(key: string, value: string): boolean;
|
|
25
|
+
export declare function safeLocalStorageRemove(key: string): void;
|
|
26
|
+
export declare function safeSessionStorageGet(key: string): string | null;
|
|
27
|
+
export declare function safeSessionStorageSet(key: string, value: string): boolean;
|
|
28
|
+
export declare function safeSessionStorageRemove(key: string): void;
|
|
29
|
+
export declare function truncateText(text: string, maxLength: number): string;
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAE/C,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAQzF;AAED,wBAAgB,YAAY,IAAI,MAAM,CAQrC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,aAAa,IAAI,WAAW,CA6B3C;AAED,wBAAgB,QAAQ,IAAI,MAAM,CA2BjC;AAED,wBAAgB,aAAa,IAAI,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAS/D;AAED,wBAAgB,aAAa,IAAI;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAMjE;AAED,wBAAgB,UAAU,IAAI,MAAM,CAGnC;AAED,wBAAgB,WAAW,IAAI,MAAM,CAGpC;AAED,wBAAgB,WAAW,IAAI,MAAM,CAGpC;AAED,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED,wBAAgB,WAAW,IAAI,MAAM,CAGpC;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ/D;AAED,wBAAgB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAavD;AAED,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM9D;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAOvE;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAMxD;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMhE;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAOzE;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAM1D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAIpE"}
|