Files
stats/apps/public/public/op1.js

495 lines
15 KiB
JavaScript

(() => {
var y = Object.create;
var c = Object.defineProperty;
var g = Object.getOwnPropertyDescriptor;
var v = Object.getOwnPropertyNames;
var m = Object.getPrototypeOf,
k = Object.prototype.hasOwnProperty;
var w = (e, s) => () => (s || e((s = { exports: {} }).exports, s), s.exports);
var b = (e, s, t, i) => {
if ((s && typeof s == 'object') || typeof s == 'function') {
for (const n of v(s)) {
!k.call(e, n) &&
n !== t &&
c(e, n, {
get: () => s[n],
enumerable: !(i = g(s, n)) || i.enumerable,
});
}
}
return e;
};
var P = (e, s, t) => (
(t = e != null ? y(m(e)) : {}),
b(
s || !e || !e.__esModule
? c(t, 'default', { value: e, enumerable: !0 })
: t,
e
)
);
var f = w((x, h) => {
h.exports = {};
});
var I = class {
constructor(e) {
(this.baseUrl = e.baseUrl),
(this.headers = {
'Content-Type': 'application/json',
...e.defaultHeaders,
}),
(this.maxRetries = e.maxRetries ?? 3),
(this.initialRetryDelay = e.initialRetryDelay ?? 500);
}
async resolveHeaders() {
const e = {};
for (const [s, t] of Object.entries(this.headers)) {
const i = await t;
i !== null && (e[s] = i);
}
return e;
}
addHeader(e, s) {
this.headers[e] = s;
}
async post(e, s, t, i) {
try {
const n = await fetch(e, {
method: 'POST',
headers: await this.resolveHeaders(),
body: s ? JSON.stringify(s ?? {}) : void 0,
keepalive: !0,
...t,
});
if (n.status === 401) {
return null;
}
if (n.status !== 200 && n.status !== 202) {
throw new Error(`HTTP error! status: ${n.status}`);
}
const r = await n.text();
return r ? JSON.parse(r) : null;
} catch (n) {
if (i < this.maxRetries) {
const r = this.initialRetryDelay * 2 ** i;
return (
await new Promise((a) => setTimeout(a, r)),
this.post(e, s, t, i + 1)
);
}
return console.error('Max retries reached:', n), null;
}
}
async fetch(e, s, t = {}) {
const i = `${this.baseUrl}${e}`;
return this.post(i, s, t, 0);
}
},
d = class {
constructor(e) {
(this.groups = []), (this.queue = []), (this.options = e);
const s = { 'openpanel-client-id': e.clientId };
e.clientSecret && (s['openpanel-client-secret'] = e.clientSecret),
(s['openpanel-sdk-name'] = e.sdk || 'node'),
(s['openpanel-sdk-version'] = e.sdkVersion || '1.3.0'),
(this.api = new I({
baseUrl: e.apiUrl || 'https://api.openpanel.dev',
defaultHeaders: s,
}));
}
init() {}
ready() {
(this.options.disabled = !1),
(this.options.waitForProfile = !1),
this.flush();
}
shouldQueue(e) {
return !!(
this.options.disabled ||
(this.options.waitForProfile && !this.profileId) ||
(e.type === 'replay' && !this.sessionId)
);
}
addQueue(e) {
e.type === 'track' &&
(e.payload.properties = {
...(e.payload.properties ?? {}),
__timestamp: new Date().toISOString(),
}),
this.queue.push(e);
}
async send(e) {
if (this.options.filter && !this.options.filter(e)) {
return Promise.resolve();
}
if (this.shouldQueue(e)) {
return this.addQueue(e), Promise.resolve();
}
const s = await this.api.fetch('/track', e, {
keepalive: e.type !== 'replay',
});
this.deviceId = s?.deviceId;
const t = !!this.sessionId;
return (
(this.sessionId = s?.sessionId),
!t && this.sessionId && this.flush(),
s
);
}
setGlobalProperties(e) {
this.global = { ...this.global, ...e };
}
track(e, s) {
this.log('track event', e, s);
const { groups: t, profileId: i, ...n } = s ?? {},
r = [...new Set([...this.groups, ...(t ?? [])])];
return this.send({
type: 'track',
payload: {
name: e,
profileId: i ?? this.profileId,
groups: r.length > 0 ? r : void 0,
properties: { ...(this.global ?? {}), ...n },
},
});
}
identify(e) {
if (
(this.log('identify user', e),
e.profileId && ((this.profileId = e.profileId), this.flush()),
Object.keys(e).length > 1)
) {
return this.send({
type: 'identify',
payload: { ...e, properties: { ...this.global, ...e.properties } },
});
}
}
upsertGroup(e) {
return (
this.log('upsert group', e), this.send({ type: 'group', payload: e })
);
}
setGroup(e) {
return (
this.log('set group', e),
this.groups.includes(e) || (this.groups = [...this.groups, e]),
this.send({
type: 'assign_group',
payload: { groupIds: [e], profileId: this.profileId },
})
);
}
setGroups(e) {
return (
this.log('set groups', e),
(this.groups = [...new Set([...this.groups, ...e])]),
this.send({
type: 'assign_group',
payload: { groupIds: e, profileId: this.profileId },
})
);
}
alias(e) {}
increment(e) {
return this.send({ type: 'increment', payload: e });
}
decrement(e) {
return this.send({ type: 'decrement', payload: e });
}
revenue(e, s) {
const t = s?.deviceId;
return (
delete s?.deviceId,
this.track('revenue', {
...(s ?? {}),
...(t ? { __deviceId: t } : {}),
__revenue: e,
})
);
}
getDeviceId() {
return this.deviceId ?? '';
}
getSessionId() {
return this.sessionId ?? '';
}
fetchDeviceId() {
return Promise.resolve(this.deviceId ?? '');
}
clear() {
(this.profileId = void 0),
(this.groups = []),
(this.deviceId = void 0),
(this.sessionId = void 0);
}
buildFlushPayload(e) {
if (e.type === 'replay') {
return e.payload;
}
if (e.type === 'track') {
const s = 'groups' in e.payload ? (e.payload.groups ?? []) : [],
t = [...new Set([...this.groups, ...s])];
return {
...e.payload,
profileId: e.payload.profileId ?? this.profileId,
groups: t.length > 0 ? t : void 0,
};
}
return e.type === 'identify' ||
e.type === 'increment' ||
e.type === 'decrement'
? { ...e.payload, profileId: e.payload.profileId ?? this.profileId }
: e.type === 'assign_group'
? { ...e.payload, profileId: e.payload.profileId ?? this.profileId }
: e.payload;
}
flush() {
const e = [];
for (const s of this.queue) {
if (this.shouldQueue(s)) {
e.push(s);
continue;
}
const t = this.buildFlushPayload(s);
this.send({ ...s, payload: t });
}
this.queue = e;
}
log(...e) {
this.options.debug && console.log('[OpenPanel.dev]', ...e);
}
};
var S = typeof document < 'u' ? document.currentScript : null;
function R(e) {
return e.replace(/([-_][a-z])/gi, (s) =>
s.toUpperCase().replace('-', '').replace('_', '')
);
}
var l = class extends d {
constructor(t) {
super({ sdk: 'web', sdkVersion: '1.3.0', ...t });
this.options = t;
this.lastPath = '';
this.pendingRevenues = [];
if (!this.isServer()) {
try {
const i = sessionStorage.getItem('openpanel-pending-revenues');
if (i) {
const n = JSON.parse(i);
Array.isArray(n) && (this.pendingRevenues = n);
}
} catch {
this.pendingRevenues = [];
}
if (
(this.setGlobalProperties({ __referrer: document.referrer }),
this.options.trackScreenViews &&
(this.trackScreenViews(), setTimeout(() => this.screenView(), 0)),
this.options.trackOutgoingLinks && this.trackOutgoingLinks(),
this.options.trackAttributes && this.trackAttributes(),
this.options.sessionReplay?.enabled)
) {
const i = this.options.sessionReplay.sampleRate ?? 1;
Math.random() < i &&
this.loadReplayModule().then((r) => {
r &&
r.startReplayRecorder(this.options.sessionReplay, (a) => {
this.send({ type: 'replay', payload: { ...a } });
});
});
}
}
}
async loadReplayModule() {
try {
{
const t = S,
i =
this.options.sessionReplay?.scriptUrl ||
t?.src?.replace('.js', '-replay.js') ||
'https://openpanel.dev/op1-replay.js';
return window.__openpanel_replay
? window.__openpanel_replay
: new Promise((n) => {
const r = document.createElement('script');
(r.src = i),
(r.onload = () => {
n(window.__openpanel_replay ?? null);
}),
(r.onerror = () => {
console.warn(
'[OpenPanel] Failed to load replay script from',
i
),
n(null);
}),
document.head.appendChild(r);
});
}
return await Promise.resolve().then(() => P(f(), 1));
} catch (t) {
return (
console.warn('[OpenPanel] Failed to load replay module', t), null
);
}
}
debounce(t, i) {
clearTimeout(this.debounceTimer), (this.debounceTimer = setTimeout(t, i));
}
isServer() {
return typeof document > 'u';
}
trackOutgoingLinks() {
this.isServer() ||
document.addEventListener('click', (t) => {
const i = t.target,
n = i.closest('a');
if (n && i) {
const r = n.getAttribute('href');
if (r?.startsWith('http')) {
try {
const a = new URL(r),
o = window.location.hostname;
a.hostname !== o &&
super.track('link_out', {
href: r,
text:
n.innerText ||
n.getAttribute('title') ||
i.getAttribute('alt') ||
i.getAttribute('title'),
});
} catch {}
}
}
});
}
trackScreenViews() {
if (this.isServer()) {
return;
}
const t = history.pushState;
history.pushState = function (...a) {
const o = t.apply(this, a);
return (
window.dispatchEvent(new Event('pushstate')),
window.dispatchEvent(new Event('locationchange')),
o
);
};
const i = history.replaceState;
(history.replaceState = function (...a) {
const o = i.apply(this, a);
return (
window.dispatchEvent(new Event('replacestate')),
window.dispatchEvent(new Event('locationchange')),
o
);
}),
window.addEventListener('popstate', () => {
window.dispatchEvent(new Event('locationchange'));
});
const n = () => this.debounce(() => this.screenView(), 50);
this.options.trackHashChanges
? window.addEventListener('hashchange', n)
: window.addEventListener('locationchange', n);
}
trackAttributes() {
this.isServer() ||
document.addEventListener('click', (t) => {
const i = t.target,
n = i.closest('button'),
r = i.closest('a'),
a = n?.getAttribute('data-track')
? n
: r?.getAttribute('data-track')
? r
: null;
if (a) {
const o = {};
for (const p of a.attributes) {
p.name.startsWith('data-') &&
p.name !== 'data-track' &&
(o[R(p.name.replace(/^data-/, ''))] = p.value);
}
const u = a.getAttribute('data-track');
u && super.track(u, o);
}
});
}
track(t, i) {
return super.track(t, { ...i, __path: this.lastPath });
}
screenView(t, i) {
if (this.isServer()) {
return;
}
let n, r;
typeof t == 'string'
? ((n = t), (r = i))
: ((n = window.location.href), (r = t)),
this.lastPath !== n &&
((this.lastPath = n),
super.track('screen_view', {
...(r ?? {}),
__path: n,
__title: document.title,
}));
}
async flushRevenue() {
const t = this.pendingRevenues.map((i) =>
super.revenue(i.amount, i.properties)
);
await Promise.all(t), this.clearRevenue();
}
clearRevenue() {
if (((this.pendingRevenues = []), !this.isServer())) {
try {
sessionStorage.removeItem('openpanel-pending-revenues');
} catch {}
}
}
pendingRevenue(t, i) {
if (
(this.pendingRevenues.push({ amount: t, properties: i }),
!this.isServer())
) {
try {
sessionStorage.setItem(
'openpanel-pending-revenues',
JSON.stringify(this.pendingRevenues)
);
} catch {}
}
}
};
((e) => {
if (e.op) {
const s = e.op.q || [],
t = new l(s.shift()[1]);
s.forEach((n) => {
n[0] in t && t[n[0]](...n.slice(1));
});
const i = new Proxy(
(n, ...r) => {
const a = t[n] ? t[n].bind(t) : void 0;
typeof a == 'function'
? a(...r)
: console.warn(`OpenPanel: ${n} is not a function`);
},
{
get(n, r) {
if (r === 'q') {
return;
}
const a = t[r];
return typeof a == 'function' ? a.bind(t) : a;
},
}
);
(e.op = i), (e.openpanel = t);
}
})(window);
})();