Skip to content

Commit

Permalink
Analytics events helper in JS Runtime (#315)
Browse files Browse the repository at this point in the history
  • Loading branch information
alshdavid authored Jan 28, 2025
1 parent d904a75 commit c789b2f
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export type AtlaspackAnalyticsEvent = {
action: string;
attributes?: {[key: string]: string | number | boolean};
};

export function sendAnalyticsEvent(event: AtlaspackAnalyticsEvent): void;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function sendAnalyticsEvent(detail) {
const ev = new globalThis.CustomEvent('atlaspack:analytics', {detail});
globalThis.dispatchEvent(ev);
}

module.exports = {sendAnalyticsEvent};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// @flow

export type AtlaspackAnalyticsEvent = {|
action: string,
attributes?: { [key: string]: string | number | boolean },
|};

declare export function sendAnalyticsEvent(event: AtlaspackAnalyticsEvent): void;
26 changes: 19 additions & 7 deletions packages/runtimes/js/src/helpers/browser/esm-js-loader-retry.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,15 @@ async function load(id) {
// Append the current time to the request URL
// to ensure it has not been cached by the browser
// eslint-disable-next-line no-undef
return await __parcel__import__(`${url}?t=${Date.now()}`);
const result = await __parcel__import__(`${url}?t=${Date.now()}`);
sendAnalyticsEvent('recovered', url, i);
return result;
} catch (error) {
if (i === maxRetries) throw error;
// Dispatch event for reporting
const event = {detail: {target: url, attempt: i}};
globalThis.dispatchEvent(
new CustomEvent('atlaspack:import_retry', event),
);
if (i === maxRetries) {
sendAnalyticsEvent('failure', url, i);
throw error;
}
sendAnalyticsEvent('progress', url, i);
}
}
})();
Expand All @@ -58,4 +59,15 @@ async function load(id) {
return retryState[url];
}

function sendAnalyticsEvent(status, targetUrl, attempt) {
require('./analytics/analytics.js').sendAnalyticsEvent({
action: 'importRetry',
attributes: {
status,
targetUrl,
attempt,
},
});
}

module.exports = load;
47 changes: 47 additions & 0 deletions packages/runtimes/js/test/analytics.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {sendAnalyticsEvent} from '../src/helpers/browser/analytics/analytics.js';
import {mock} from 'node:test';
import type {Mock} from 'node:test';
import assert from 'node:assert';

describe('@atlaspack/analytics', () => {
let dispatchEventMock: Mock<Window['dispatchEvent']>;

beforeEach(() => {
// @ts-expect-error
globalThis.CustomEvent = MockCustomEvent;
dispatchEventMock = mock.fn();
globalThis.dispatchEvent = dispatchEventMock;
});

it('should not throw', () => {
assert.doesNotThrow(() =>
sendAnalyticsEvent({
action: 'test',
}),
);
});

it('should raise event on window', () => {
sendAnalyticsEvent({
action: 'test',
});

assert.equal(dispatchEventMock.mock.callCount(), 1);
assert.deepEqual(dispatchEventMock.mock.calls[0].arguments[0], {
eventName: 'atlaspack:analytics',
detail: {
action: 'test',
},
});
});
});

class MockCustomEvent {
eventName: string;
detail: any;

constructor(eventName: string, options: any = {}) {
this.eventName = eventName;
this.detail = options.detail;
}
}

0 comments on commit c789b2f

Please sign in to comment.