UNPKG

@aws-amplify/analytics

Version:

Analytics category of aws-amplify

180 lines (152 loc) 4.29 kB
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 // the session tracker for web import { ConsoleLogger as Logger, Hub, Constants, browserOrNode, } from '@aws-amplify/core'; import { SessionTrackOpts } from '../types'; const logger = new Logger('SessionTracker'); const defaultOpts: SessionTrackOpts = { enable: false, provider: 'AWSPinpoint', }; let initialEventSent = false; export class SessionTracker { private _tracker; private _hasEnabled; private _config: SessionTrackOpts; private _hidden; private _visibilityChange; constructor(tracker, opts) { this._config = Object.assign({}, defaultOpts, opts); this._tracker = tracker; this._hasEnabled = false; this._trackFunc = this._trackFunc.bind(this); this._trackBeforeUnload = this._trackBeforeUnload.bind(this); this.configure(this._config); } private _envCheck() { if (!browserOrNode().isBrowser) { return false; } if (!document || !document.addEventListener) { logger.debug('not in the supported web environment'); return false; } if (typeof document.hidden !== 'undefined') { this._hidden = 'hidden'; this._visibilityChange = 'visibilitychange'; } else if (typeof document['msHidden'] !== 'undefined') { this._hidden = 'msHidden'; this._visibilityChange = 'msvisibilitychange'; } else if (typeof document['webkitHidden'] !== 'undefined') { this._hidden = 'webkitHidden'; this._visibilityChange = 'webkitvisibilitychange'; } else { logger.debug('not in the supported web environment'); return false; } return true; } private async _trackFunc() { const customAttrs = typeof this._config.attributes === 'function' ? await this._config.attributes() : this._config.attributes; const attributes = Object.assign({}, customAttrs); if (document.visibilityState === this._hidden) { this._tracker( { name: '_session.stop', attributes, }, this._config.provider ).catch(e => { logger.debug('record session stop event failed.', e); }); } else { this._tracker( { name: '_session.start', attributes, }, this._config.provider ).catch(e => { logger.debug('record session start event failed.', e); }); } } private _trackBeforeUnload(event) { // before unload callback cannot be async => https://github.com/aws-amplify/amplify-js/issues/2088 const customAttrs = typeof this._config.attributes === 'function' ? Promise.resolve(this._config.attributes()) : Promise.resolve(this._config.attributes); customAttrs.then(custom => { const attributes = Object.assign({}, custom); this._tracker( { name: '_session.stop', attributes, immediate: true, }, this._config.provider ).catch(e => { logger.debug('record session stop event failed.', e); }); }); } // to keep configure a synchronized function private async _sendInitialEvent() { if (initialEventSent) { logger.debug('the start session has been sent when the page is loaded'); return; } else { initialEventSent = true; } const customAttrs = typeof this._config.attributes === 'function' ? await this._config.attributes() : this._config.attributes; const attributes = Object.assign({}, customAttrs); this._tracker( { name: '_session.start', attributes, }, this._config.provider ).catch(e => { logger.debug('record session start event failed.', e); }); } configure(opts?: SessionTrackOpts) { if (!this._envCheck()) { return this._config; } Object.assign(this._config, opts); if (this._config.enable && !this._hasEnabled) { // send a start session as soon as it's enabled this._sendInitialEvent(); // listen on events document.addEventListener(this._visibilityChange, this._trackFunc, false); window.addEventListener('beforeunload', this._trackBeforeUnload, false); this._hasEnabled = true; } else if (!this._config.enable && this._hasEnabled) { document.removeEventListener( this._visibilityChange, this._trackFunc, false ); window.removeEventListener( 'beforeunload', this._trackBeforeUnload, false ); this._hasEnabled = false; } return this._config; } }