@wener/console
Version:
Base console UI toolkit
120 lines (113 loc) • 2.97 kB
text/typescript
import { getGlobalThis } from '@wener/utils';
import { createStore } from 'zustand';
import { mutative } from 'zustand-mutative';
import type { MatomoTracker } from './types';
function setupMatomo({
global = getGlobalThis(),
url,
siteId,
queue = [],
}: {
global?: any;
siteId?: string;
url?: string;
queue?: any[];
} = {}) {
if (!url || !siteId) {
return;
}
const G = global;
if (typeof G === 'undefined' || G['Matomo']?.initialized) {
return;
}
const _paq = (G._paq = G._paq || queue);
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
const u = url;
_paq.push(['setTrackerUrl', u + 'matomo.php']);
_paq.push(['setSiteId', siteId]);
return new Promise((resolve, reject) => {
const doc = document;
const ele$ = doc.createElement('script');
const parent$ = doc.getElementsByTagName('script')[0];
ele$.onload = () => {
resolve(window.Matomo);
};
ele$.onerror = reject;
ele$.type = 'text/javascript';
ele$.async = true;
ele$.defer = true;
ele$.src = u + 'matomo.js';
parent$.parentNode?.insertBefore(ele$, parent$);
});
}
interface TrackerStoreState {
tracker: MatomoTracker;
init: (o: { baseUrl?: string; siteId?: string }) => void;
}
export const TrackerStore = createStore<TrackerStoreState>()(
mutative((setState, getState, store) => {
const g: any = getGlobalThis();
const queue: any[] = [];
let pending;
return {
init: ({ baseUrl, siteId }) => {
pending ||= setupMatomo({
url: baseUrl,
siteId: siteId,
});
},
tracker: createProxyTracker({
queue,
invoke: ({ method, args }) => {},
}),
} as TrackerStoreState;
}),
);
function createProxyTracker({
queue = [],
invoke,
}: {
queue?: any[];
invoke?: (o: { method: string; args: any[]; queue: any[] }) => void | boolean;
}): MatomoTracker {
return new Proxy(
{
_paq: queue,
},
{
get(target, prop) {
switch (prop) {
case '_paq':
return target._paq;
}
return (...args: any[]) => {
switch (prop) {
case 'push':
queue.push(...args);
return;
default:
if (typeof prop !== 'string') {
throw new Error(`Invalid tracker method ${String(prop)}`);
}
}
let skip = false;
if (invoke) {
skip = invoke?.({ method: prop, args, queue }) === true;
}
if (!skip) {
queue.push([prop, ...args]);
}
// Limit queue size
if (queue.length > 1000) {
queue.splice(0, 1000 - queue.length);
}
};
},
},
) as any;
}
export function getTracker(): MatomoTracker {
return TrackerStore.getState().tracker;
}