Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Web Worker and ServiceWorker scope #45

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ npm-debug.log
yarn-error.log
package-lock.json
packages/*/dist
packages/*/tests/coverage
packages/*/tests/coverage
.DS_Store
50 changes: 25 additions & 25 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,32 @@
]
},
"devDependencies": {
"@babel/core": "^7.17.10",
"@babel/preset-env": "^7.17.10",
"@commitlint/cli": "^17.0.3",
"@commitlint/config-conventional": "^17.0.3",
"@types/jest": "^27.5.1",
"@types/node": "^17.0.33",
"@typescript-eslint/eslint-plugin": "^5.23.0",
"@typescript-eslint/parser": "^5.23.0",
"babel-jest": "^28.1.0",
"babel-loader": "^8.2.5",
"eslint": "^8.15.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-jest": "^26.1.5",
"husky": "^8.0.1",
"jest": "^28.1.1",
"jest-environment-jsdom": "^28.1.0",
"lerna": "^4.0.0",
"@babel/core": "^7.21.4",
"@babel/preset-env": "^7.21.4",
"@commitlint/cli": "^17.6.1",
"@commitlint/config-conventional": "^17.6.1",
"@types/jest": "^29.5.0",
"@types/node": "^18.15.11",
"@typescript-eslint/eslint-plugin": "^5.58.0",
"@typescript-eslint/parser": "^5.58.0",
"babel-jest": "^29.5.0",
"babel-loader": "^9.1.2",
"eslint": "^8.38.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-jest": "^27.2.1",
"husky": "^8.0.3",
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0",
"lerna": "^6.6.1",
"npm-run-all": "^4.1.5",
"prettier": "^2.6.2",
"rimraf": "^3.0.2",
"ts-jest": "^28.0.2",
"ts-loader": "^9.3.0",
"ts-node": "^10.7.0",
"typescript": "^4.6.4",
"webpack": "^5.72.1",
"webpack-cli": "^4.9.2",
"prettier": "^2.8.7",
"rimraf": "^5.0.0",
"ts-jest": "^29.1.0",
"ts-loader": "^9.4.2",
"ts-node": "^10.9.1",
"typescript": "^5.0.4",
"webpack": "^5.79.0",
"webpack-cli": "^5.0.1",
"webpack-node-externals": "^3.0.0"
}
}
2 changes: 1 addition & 1 deletion packages/ga4/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@minimal-analytics/ga4",
"version": "1.8.7",
"version": "1.8.8",
"description": "A tiny (2KB GZipped) version of GA4, complete with page view, engagement, scroll and click tracking",
"author": "James Hill <contact@jameshill.dev>",
"homepage": "https://github.com/jahilldev/minimal-analytics/tree/main/packages/ga4#readme",
Expand Down
49 changes: 27 additions & 22 deletions packages/ga4/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ import {
isTargetElement,
getUrlData,
getEventParams,
mergeEventParams,
EventParamArray,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: This seems to be very similar to the following type, can we re-use that instead?

type EventParams = Record<string, ParamValue> | [string, ParamValue][];

} from '@minimal-analytics/shared';
import type { EventParams } from '@minimal-analytics/shared';
import { sendBeacon } from '@minimal-analytics/shared';
import { param, files } from './model';

/* -----------------------------------
Expand Down Expand Up @@ -50,8 +53,8 @@ interface IProps {
* -------------------------------- */

const isBrowser = typeof window !== 'undefined';
const defineGlobal = isBrowser && window.minimalAnalytics?.defineGlobal;
const autoTrack = isBrowser && window.minimalAnalytics?.autoTrack;
const defineGlobal = isBrowser && globalThis.minimalAnalytics?.defineGlobal;
const autoTrack = isBrowser && globalThis.minimalAnalytics?.autoTrack;
const analyticsEndpoint = 'https://www.google-analytics.com/g/collect';
const searchTerms = ['q', 's', 'search', 'query', 'keyword'];
const clickTargets = 'a, button, input[type=submit], input[type=button]';
Expand Down Expand Up @@ -83,7 +86,7 @@ const eventKeys = {
* -------------------------------- */

function getArguments(args: any[]): [string | undefined, IProps] {
const globalId = window.minimalAnalytics?.trackingId;
const globalId = globalThis.minimalAnalytics?.trackingId;
const trackingId = typeof args[0] === 'string' ? args[0] : globalId;
const props = typeof args[0] === 'object' ? args[0] : args[1] || {};

Expand All @@ -96,8 +99,8 @@ function getArguments(args: any[]): [string | undefined, IProps] {
*
* -------------------------------- */

function getEventMeta({ type = '', event }: Pick<IProps, 'type' | 'event'>) {
const searchString = document.location.search;
function getEventMeta({ type = '', event }: Pick<IProps, 'type' | 'event'>): EventParamArray {
const searchString = globalThis.document?.location?.search || globalThis.location?.search || '';
const searchParams = new URLSearchParams(searchString);

const searchResults = searchTerms.some((term) =>
Expand All @@ -107,13 +110,13 @@ function getEventMeta({ type = '', event }: Pick<IProps, 'type' | 'event'>) {
const eventName = searchResults ? eventKeys.viewSearchResults : type;
const searchTerm = searchTerms.find((term) => searchParams.get(term));

let eventParams = [
let eventParams: EventParamArray = [
[param.eventName, eventName],
[`${param.eventParam}.search_term`, searchTerm || ''],
];

if (event) {
eventParams = eventParams.concat(getEventParams(event));
eventParams = mergeEventParams(eventParams, getEventParams(event));
}

return eventParams;
Expand All @@ -130,7 +133,7 @@ function getQueryParams(trackingId: string, { type, event, debug }: IProps) {
const { firstVisit, sessionStart, sessionCount } = getSessionState(!trackCalled);
const screen = self.screen || ({} as Screen);

let params = [
let params: EventParamArray = [
[param.protocolVersion, '2'],
[param.trackingId, trackingId],
[param.pageId, getRandomId()],
Expand All @@ -149,7 +152,7 @@ function getQueryParams(trackingId: string, { type, event, debug }: IProps) {
[param.screenResolution, `${screen.width}x${screen.height}`],
];

params = params.concat(getEventMeta({ type, event }));
params = mergeEventParams(params, getEventMeta({ type, event }));
params = params.filter(([, value]) => value);

return new URLSearchParams(params);
Expand Down Expand Up @@ -258,7 +261,7 @@ function onFocusEvent() {
function onVisibilityChange() {
const timeIndex = engagementTimes.length - 1;
const [, isHidden] = engagementTimes[timeIndex];
const stateIndex = ['hidden', 'visible'].indexOf(document.visibilityState);
const stateIndex = ['hidden', 'visible'].indexOf(globalThis.document?.visibilityState || '');
const isVisible = Boolean(stateIndex);

if (stateIndex === -1) {
Expand Down Expand Up @@ -294,7 +297,7 @@ const onScrollEvent = debounce((trackingId: string) => {
event: eventParams,
});

document.removeEventListener('scroll', scrollHandler);
globalThis.document?.removeEventListener('scroll', scrollHandler);
});

/* -----------------------------------
Expand Down Expand Up @@ -327,13 +330,13 @@ function bindEvents(trackingId: string) {
scrollHandler = onScrollEvent.bind(null, trackingId);
unloadHandler = onUnloadEvent.bind(null, trackingId);

document.addEventListener('visibilitychange', onVisibilityChange);
document.addEventListener('scroll', scrollHandler);
document.addEventListener('click', clickHandler);
globalThis.document?.addEventListener('visibilitychange', onVisibilityChange);
globalThis.document?.addEventListener('scroll', scrollHandler);
globalThis.document?.addEventListener('click', clickHandler);

window.addEventListener('blur', onBlurEvent);
window.addEventListener('focus', onFocusEvent);
window.addEventListener('beforeunload', unloadHandler);
globalThis.addEventListener('blur', onBlurEvent);
globalThis.addEventListener('focus', onFocusEvent);
globalThis.addEventListener('beforeunload', unloadHandler);
}

/* -----------------------------------
Expand All @@ -354,11 +357,13 @@ function track(...args: any[]) {
}

const queryParams = getQueryParams(trackingId, { type, event, debug });
const endpoint = window.minimalAnalytics?.analyticsEndpoint || analyticsEndpoint;
const endpoint = globalThis.minimalAnalytics?.analyticsEndpoint || analyticsEndpoint;

navigator.sendBeacon(`${endpoint}?${queryParams}`);
sendBeacon(`${endpoint}?${queryParams}`);

bindEvents(trackingId);
if (isBrowser) {
bindEvents(trackingId);
}

trackCalled = true;
}
Expand All @@ -369,8 +374,8 @@ function track(...args: any[]) {
*
* -------------------------------- */

if (defineGlobal) {
window.track = track;
if (defineGlobal && globalThis) {
globalThis.track = track;
}

/* -----------------------------------
Expand Down
Loading