Files
dukang/packages/client-logging/src/analytics.ts
T
2026-08-04 21:38:49 +08:00

141 lines
3.7 KiB
TypeScript

import { postJson, type PostJson } from './http';
import { getSessionId } from './session';
export type TrackParams = Record<string, unknown>;
export type UserTrackerOptions = {
apiBase: string;
clientApp: string;
getToken?: () => string | null;
postJson?: PostJson;
getPagePath?: () => string | undefined;
};
function resolvePagePath(getPagePath?: () => string | undefined): string | undefined {
if (getPagePath) return getPagePath();
if (typeof window !== 'undefined') return window.location.pathname;
return undefined;
}
export function createUserTracker(opts: UserTrackerOptions) {
const send = opts.postJson ?? postJson;
const getToken = opts.getToken ?? (() =>
typeof localStorage !== 'undefined' ? localStorage.getItem('accessToken') : null);
function track(eventName: string, params?: TrackParams) {
const sessionId = getSessionId();
const token = getToken();
const headers: Record<string, string> = {
'Content-Type': 'application/json',
'X-Client-App': opts.clientApp,
};
if (token) headers.Authorization = `Bearer ${token}`;
send({
url: `${opts.apiBase}/analytics/events`,
headers,
body: {
sessionId,
clientApp: opts.clientApp,
events: [{ eventName, params: { sessionId, ...params } }],
},
});
}
function trackPageView(eventName: string, params?: TrackParams) {
track(eventName, {
pagePath: resolvePagePath(opts.getPagePath),
...params,
});
}
function trackSessionStart() {
track('session_start', {
pagePath: resolvePagePath(opts.getPagePath),
});
}
return { track, trackPageView, trackSessionStart };
}
export type StoreTrackerOptions = {
apiBase: string;
clientApp: string;
getToken: () => string | null;
getStoreId: () => string | null;
postJson?: PostJson;
getPagePath?: () => string | undefined;
};
export function createStoreTracker(opts: StoreTrackerOptions) {
const send = opts.postJson ?? postJson;
function track(eventName: string, params?: TrackParams) {
const token = opts.getToken();
const storeId = opts.getStoreId();
if (!token || !storeId) return;
send({
url: `${opts.apiBase}/analytics/store-events`,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
'X-Client-App': opts.clientApp,
},
body: {
sessionId: getSessionId(),
storeId,
events: [{ eventName, params: { sessionId: getSessionId(), storeId, ...params } }],
},
});
}
function trackPageView(eventName: string, params?: TrackParams) {
track(eventName, {
pagePath: resolvePagePath(opts.getPagePath),
...params,
});
}
return { track, trackPageView };
}
export type PartnerTrackerOptions = {
apiBase: string;
clientApp: string;
getToken: () => string | null;
postJson?: PostJson;
getPagePath?: () => string | undefined;
};
export function createPartnerTracker(opts: PartnerTrackerOptions) {
const send = opts.postJson ?? postJson;
function track(eventName: string, params?: TrackParams) {
const token = opts.getToken();
if (!token) return;
send({
url: `${opts.apiBase}/analytics/partner-events`,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
'X-Client-App': opts.clientApp,
},
body: {
sessionId: getSessionId(),
events: [{ eventName, params: { sessionId: getSessionId(), ...params } }],
},
});
}
function trackPageView(eventName: string, params?: TrackParams) {
track(eventName, {
pagePath: resolvePagePath(opts.getPagePath),
...params,
});
}
return { track, trackPageView };
}