import { Runner } from "../commons/types/runner"; import { CookieUtils } from "../commons/utils/cookie-utils"; import { Logger } from "../commons/utils/logger"; import { SessionUtils } from "../commons/utils/session-utils"; import { SessionStartEvent } from "../event/types/session/start"; import { EventQueue } from "../commons/utils/event-queue"; /** * Main Bundle. Responsible for starting all products. * * @class Bundle */ export abstract class Bundle { /** * Add runners to the bundle. * * @static * @param {Runner} runner Runner to use. * @memberof Bundle */ public static use(runner: Runner): void { this.runners.push(runner); } /** * Run the bundle. * * @static * @return {Promise} * @memberof Bundle */ public static async run(): Promise { try { if (!CookieUtils.enabled) { // TODO: Here we should have some kind of metric. // This metric would be used to track how many PageViews we are losing from // disabled cookies. return; } this.createDataLayer(); await EventQueue.resend(); await this.startSession(); for (const runner of this.runners) { // We need to start a background task that awaits on `runner.start`, so that // every error thrown in `runner.start` can be successfully logged. const startBackground = async (): Promise => { try { await runner.start(); } catch (err) { Logger.log(err); } }; startBackground(); } } catch (err) { Logger.log(err); } } private static runners: Runner[] = []; /** * Create the default dataLayer and instantiate all * it's properties with default values. * * @private * @static * @memberof Bundle */ private static createDataLayer(): void { if (!window.dataLayer) { window.dataLayer = []; } } /** * Start a new Session. Creates `sessionId` and `anonymousId`. * * @private * @static * @memberof Bundle */ private static async startSession(): Promise { if (!SessionUtils.isNewSession()) { return; } // Setting the anonymous and sessionId. SessionUtils.getAnonymous(); SessionUtils.getSession(); // This is event is sent from outside the EventRunner because all services should // use the same session API, so starting a session should be centralized and done // only once. await new SessionStartEvent().push(); } }