@gumlet/insights-js-core 1.0.3 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/main.yml +87 -0
- package/.gitlab-ci.yml +54 -0
- package/LICENSE +21 -0
- package/README.md +30 -0
- package/bitbucket-pipelines.yml +35 -0
- package/docs/payload-documentation.md +72 -0
- package/html/bitmovin.html +82 -0
- package/html/dashjs.html +55 -0
- package/html/hlsjs.html +72 -0
- package/html/html5.html +59 -0
- package/html/shaka.html +102 -0
- package/html/videojs.html +67 -0
- package/index.html +73 -0
- package/jest.config.js +187 -0
- package/js/adapters/Bitmovin7Adapter.js +352 -0
- package/js/adapters/BitmovinAdapter.js +198 -0
- package/js/adapters/DashjsAdapter.js +140 -0
- package/js/adapters/HTML5Adapter.js +774 -0
- package/js/adapters/HlsjsAdapter.js +152 -0
- package/js/adapters/ShakaAdapter.js +81 -0
- package/js/adapters/VideoJsAdapter.js +455 -0
- package/js/analyticsStateMachines/Bitmovin7AnalyticsStateMachine.js +471 -0
- package/js/analyticsStateMachines/BitmovinAnalyticsStateMachine.js +299 -0
- package/js/analyticsStateMachines/HTML5AnalyticsStateMachine.js +443 -0
- package/js/analyticsStateMachines/VideoJsAnalyticsStateMachine.js +503 -0
- package/js/cast/CastClient.js +50 -0
- package/js/cast/CastReceiver.js +37 -0
- package/js/core/AdapterFactory.js +41 -0
- package/js/core/Analytics.js +1364 -0
- package/js/core/AnalyticsStateMachineFactory.js +36 -0
- package/js/core/GumletInsightsExport.js +75 -0
- package/js/enums/CDNProviders.js +11 -0
- package/js/enums/Events.js +32 -0
- package/js/enums/GumletEnum.js +19 -0
- package/js/enums/MIMETypes.js +30 -0
- package/js/enums/Players.js +11 -0
- package/js/enums/StreamTypes.js +15 -0
- package/js/utils/EventsCall.js +22 -0
- package/js/utils/HttpCall.js +57 -0
- package/js/utils/LicenseCall.js +18 -0
- package/js/utils/Logger.js +40 -0
- package/js/utils/PlayerDetector.js +75 -0
- package/js/utils/PlayerInitCall.js +22 -0
- package/js/utils/SessionCreationCall.js +22 -0
- package/js/utils/Settings.js +3 -0
- package/js/utils/Utils.js +195 -0
- package/package.json +62 -1
- package/precommit.bash +8 -0
- package/tests/stage1.test.js +50 -0
- package/webpack.config.debug.js +34 -0
- package/webpack.config.js +40 -0
- package/webpack.config.release.js +62 -0
- package/gumlet-insights.min.js +0 -2
- package/gumlet-insights.min.js.LICENSE.txt +0 -10
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import PlayerDetector from '../utils/PlayerDetector';
|
|
2
|
+
import {BitmovinAnalyticsStateMachine} from '../analyticsStateMachines/BitmovinAnalyticsStateMachine';
|
|
3
|
+
import {Bitmovin7AnalyticsStateMachine} from '../analyticsStateMachines/Bitmovin7AnalyticsStateMachine';
|
|
4
|
+
import {VideojsAnalyticsStateMachine} from '../analyticsStateMachines/VideoJsAnalyticsStateMachine';
|
|
5
|
+
import {HTML5AnalyticsStateMachine} from '../analyticsStateMachines/HTML5AnalyticsStateMachine';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Stateless. Auto-maps given player instance to new state-machine instances.
|
|
9
|
+
* @class
|
|
10
|
+
*/
|
|
11
|
+
class AnalyticsStateMachineFactory {
|
|
12
|
+
/**
|
|
13
|
+
* @param {object} player
|
|
14
|
+
* @param {AnalyticsStateMachineCallbacks} stateMachineCallbacks
|
|
15
|
+
* @param {AnalyticsStateMachineOptions} opts
|
|
16
|
+
*/
|
|
17
|
+
static getAnalyticsStateMachine(player, stateMachineCallbacks, opts = {}) {
|
|
18
|
+
if (PlayerDetector.isBitmovinVersionPre7(player)) {
|
|
19
|
+
return new BitmovinAnalyticsStateMachine(stateMachineCallbacks, opts);
|
|
20
|
+
} else if (PlayerDetector.isBitmovinVersion7Plus(player)) {
|
|
21
|
+
return new Bitmovin7AnalyticsStateMachine(stateMachineCallbacks, opts);
|
|
22
|
+
} else if (PlayerDetector.isVideoJs(player)) {
|
|
23
|
+
return new VideojsAnalyticsStateMachine(stateMachineCallbacks, opts);
|
|
24
|
+
} else if (
|
|
25
|
+
PlayerDetector.isHlsjs(player) ||
|
|
26
|
+
PlayerDetector.isDashjs(player) ||
|
|
27
|
+
PlayerDetector.isShaka(player)) {
|
|
28
|
+
return new HTML5AnalyticsStateMachine(stateMachineCallbacks, opts);
|
|
29
|
+
} else {
|
|
30
|
+
// throw new Error('Could not detect player type');
|
|
31
|
+
return new HTML5AnalyticsStateMachine(stateMachineCallbacks, opts);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default AnalyticsStateMachineFactory;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import Analytics from './Analytics';
|
|
2
|
+
import {Players} from '../enums/Players';
|
|
3
|
+
import CdnProviders from '../enums/CDNProviders';
|
|
4
|
+
import EVENTS from "../enums/Events";
|
|
5
|
+
|
|
6
|
+
let analytics;
|
|
7
|
+
|
|
8
|
+
const register = (player, opts = {}) => {
|
|
9
|
+
return analytics.register(player, opts);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const registerVideoJSPlayer = (player, opts = {}) => {
|
|
13
|
+
return analytics.registerVideoJSPlayer(player, opts);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const registerDashJSPlayer = (player, opts = {}) => {
|
|
17
|
+
return analytics.registerDashJSPlayer(player, opts);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const registerHLSJSPlayer = (player, opts = {}) => {
|
|
21
|
+
return analytics.registerHLSJSPlayer(player, opts);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const registerShakaPlayer = (player, opts = {}) => {
|
|
25
|
+
return analytics.registerShakaPlayer(player, opts);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const registerHTML5Player = (player, opts = {}) => {
|
|
29
|
+
return analytics.registerHTML5Player(player, opts);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const registerReactNativeVideoPlayer = (player, opts = {}) => {
|
|
33
|
+
return analytics.registerReactNativeVideoPlayer(player, opts);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const getCurrentImpressionId = () => {
|
|
37
|
+
return analytics.getCurrentImpressionId();
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const getAnalyticsStateMachine = () => {
|
|
41
|
+
return analytics.analyticsStateMachine;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const analyticsWrapper = (config) => {
|
|
45
|
+
analytics = new Analytics(config);
|
|
46
|
+
return {
|
|
47
|
+
register : register,
|
|
48
|
+
registerVideoJSPlayer : registerVideoJSPlayer,
|
|
49
|
+
registerDashJSPlayer : registerDashJSPlayer,
|
|
50
|
+
registerHLSJSPlayer : registerHLSJSPlayer,
|
|
51
|
+
registerShakaPlayer : registerShakaPlayer,
|
|
52
|
+
registerHTML5Player : registerHTML5Player,
|
|
53
|
+
registerReactNativeVideoPlayer: registerReactNativeVideoPlayer,
|
|
54
|
+
getCurrentImpressionId : getCurrentImpressionId,
|
|
55
|
+
stateMachine : getAnalyticsStateMachine,
|
|
56
|
+
setCustomData : analytics.setCustomData,
|
|
57
|
+
setCustomDataOnce : analytics.setCustomDataOnce,
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
analyticsWrapper.Players = Players;
|
|
62
|
+
analyticsWrapper.CdnProviders = CdnProviders;
|
|
63
|
+
|
|
64
|
+
if (typeof window !== "undefined")
|
|
65
|
+
{
|
|
66
|
+
window.gumlet = window.gumlet || {};
|
|
67
|
+
window.gumlet.insights = analyticsWrapper;
|
|
68
|
+
window.gumletInsightsEvents = EVENTS;
|
|
69
|
+
window.gumletSupportedPlayers = Players;
|
|
70
|
+
}
|
|
71
|
+
else{
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export default analyticsWrapper;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const Events = {
|
|
2
|
+
READY : 'ready',
|
|
3
|
+
STARTUP : 'startup',
|
|
4
|
+
SOURCE_LOADED : 'sourceLoaded',
|
|
5
|
+
PLAY : 'play',
|
|
6
|
+
PAUSE : 'pause',
|
|
7
|
+
TIMECHANGED : 'timechanged',
|
|
8
|
+
SEEK : 'seek',
|
|
9
|
+
SEEKED : 'seeked',
|
|
10
|
+
START_CAST : 'startCasting',
|
|
11
|
+
END_CAST : 'endCasting',
|
|
12
|
+
START_BUFFERING : 'startBuffering',
|
|
13
|
+
END_BUFFERING : 'endBuffering',
|
|
14
|
+
AUDIO_CHANGE : 'audioChange',
|
|
15
|
+
VIDEO_CHANGE : 'videoChange',
|
|
16
|
+
START_FULLSCREEN : 'startFullscreen',
|
|
17
|
+
END_FULLSCREEN : 'endFullscreen',
|
|
18
|
+
START_AD : 'adStart',
|
|
19
|
+
END_AD : 'adEnd',
|
|
20
|
+
MUTE : 'mute',
|
|
21
|
+
UN_MUTE : 'unMute',
|
|
22
|
+
ERROR : 'playerError',
|
|
23
|
+
PLAYBACK_FINISHED: 'end',
|
|
24
|
+
SCREEN_RESIZE : 'resize',
|
|
25
|
+
UNLOAD : 'unload',
|
|
26
|
+
END : 'end',
|
|
27
|
+
METADATA_LOADED : 'metadataLoaded',
|
|
28
|
+
SOURCE_UNLOADED : 'sourceUnloaded',
|
|
29
|
+
PLAYBACK_PLAYING : 'playback_playing',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default Events;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const GumletEventEnum = {
|
|
2
|
+
SETUP : 'event_setup',
|
|
3
|
+
PLAYER_READY : 'event_player_ready',
|
|
4
|
+
PLAYBACK_READY : 'event_playback_ready',
|
|
5
|
+
PLAYBACK_STARTED : 'event_playback_started',
|
|
6
|
+
PAUSE : 'event_pause',
|
|
7
|
+
PLAY : 'event_play',
|
|
8
|
+
PLAYING : 'event_playing',
|
|
9
|
+
PLAYBACK_UPDATE : 'event_playback_update',
|
|
10
|
+
END : 'event_ended',
|
|
11
|
+
MUTE : 'event_muted',
|
|
12
|
+
UNMUTE : 'event_unmute',
|
|
13
|
+
SEEKED : 'event_seeked',
|
|
14
|
+
START_REBUFFER : 'event_rebuffer_start',
|
|
15
|
+
END_REBUFFER : 'event_rebuffer_end',
|
|
16
|
+
ERROR : 'event_error',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default GumletEventEnum;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const MP4 = 'video/mp4';
|
|
2
|
+
const WEBM = 'video/webm';
|
|
3
|
+
const HLS = 'application/x-mpegURL';
|
|
4
|
+
const DASH = 'application/dash+xml';
|
|
5
|
+
|
|
6
|
+
export const MIMETypes = {
|
|
7
|
+
MP4,
|
|
8
|
+
WEBM,
|
|
9
|
+
HLS,
|
|
10
|
+
DASH
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function getMIMETypeFromFileExtension(path) {
|
|
14
|
+
|
|
15
|
+
path = path.toLowerCase();
|
|
16
|
+
|
|
17
|
+
if (path.endsWith('.m3u8')) {
|
|
18
|
+
return HLS;
|
|
19
|
+
}
|
|
20
|
+
if (path.endsWith('.mp4') || path.endsWith('.m4v') || path.endsWith('.m4a')) {
|
|
21
|
+
return MP4;
|
|
22
|
+
}
|
|
23
|
+
if (path.endsWith('.webm')) {
|
|
24
|
+
return WEBM;
|
|
25
|
+
}
|
|
26
|
+
if (path.endsWith('.mpd')) {
|
|
27
|
+
return DASH;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {MIMETypes} from './MIMETypes';
|
|
2
|
+
|
|
3
|
+
const { MP4, WEBM, HLS, DASH } = MIMETypes;
|
|
4
|
+
|
|
5
|
+
const mapping = {
|
|
6
|
+
[MP4]: 'mp4',
|
|
7
|
+
[WEBM]: 'webm',
|
|
8
|
+
[HLS]: 'hls',
|
|
9
|
+
[DASH]: 'dash'
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function getStreamTypeFromMIMEType(mimeType) {
|
|
13
|
+
return mapping[mimeType];
|
|
14
|
+
}
|
|
15
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import HttpCall from './HttpCall';
|
|
2
|
+
import {ANALYTICS_BACKEND_BASE_URL} from './Settings';
|
|
3
|
+
|
|
4
|
+
class EventsCall extends HttpCall{
|
|
5
|
+
static analyticsServerUrl = ANALYTICS_BACKEND_BASE_URL;
|
|
6
|
+
|
|
7
|
+
sendRequest = function(sample, callback) {
|
|
8
|
+
sample.event_family = 'session_event';
|
|
9
|
+
this.get(EventsCall.analyticsServerUrl, sample, callback);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
sendRequestSynchronous = function(sample, callback) {
|
|
13
|
+
sample.event_family = 'session_event';
|
|
14
|
+
this.get(EventsCall.analyticsServerUrl, sample, callback, false);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
getAnalyticsServerUrl = function() {
|
|
18
|
+
return EventsCall.analyticsServerUrl;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default EventsCall;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import Utils from '../utils/Utils';
|
|
2
|
+
|
|
3
|
+
class HttpCall {
|
|
4
|
+
get(url, body, callback, async = true) {
|
|
5
|
+
let xhttp;
|
|
6
|
+
let legacyMode = false;
|
|
7
|
+
|
|
8
|
+
if (window.XDomainRequest) {
|
|
9
|
+
legacyMode = true;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (legacyMode) {
|
|
13
|
+
xhttp = new window.XDomainRequest();
|
|
14
|
+
} else {
|
|
15
|
+
xhttp = new XMLHttpRequest();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const responseCallback = function() {
|
|
19
|
+
if (xhttp.readyState == XMLHttpRequest.DONE) {
|
|
20
|
+
if (xhttp.responseText <= 0) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const sampleResponse = JSON.parse(xhttp.responseText);
|
|
25
|
+
|
|
26
|
+
callback(sampleResponse);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
if (legacyMode) {
|
|
31
|
+
xhttp.onload = responseCallback;
|
|
32
|
+
} else {
|
|
33
|
+
xhttp.onreadystatechange = responseCallback;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// TODO: resolve to milliseconds
|
|
37
|
+
body['z'] = (new Date()).getTime()/1000;
|
|
38
|
+
|
|
39
|
+
const removeUnwantedValues = [undefined, null, false]
|
|
40
|
+
|
|
41
|
+
// Body cleanup
|
|
42
|
+
Object.keys(body).forEach(key => removeUnwantedValues.indexOf(body[key]) !== -1 && delete body[key])
|
|
43
|
+
// Remove NaN from payload
|
|
44
|
+
// Since NaN is the only JavaScript value that is treated as unequal to itself
|
|
45
|
+
Object.keys(body).forEach(key => body[key] !== body[key] && delete body[key])
|
|
46
|
+
|
|
47
|
+
// Create the queryString for URL
|
|
48
|
+
let queryString = Utils.jsonToQueryString(body);
|
|
49
|
+
url += queryString;
|
|
50
|
+
|
|
51
|
+
xhttp.open('GET', url, async);
|
|
52
|
+
|
|
53
|
+
xhttp.send(null);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default HttpCall;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import HttpCall from './HttpCall';
|
|
2
|
+
import {ANALYTICS_BACKEND_BASE_URL} from './Settings';
|
|
3
|
+
|
|
4
|
+
class LicenseCall extends HttpCall {
|
|
5
|
+
static licenseServerUrl = ANALYTICS_BACKEND_BASE_URL + '/licensing';
|
|
6
|
+
|
|
7
|
+
sendRequest = function(key, domain, version, callback) {
|
|
8
|
+
const licensingRequest = {
|
|
9
|
+
key: key,
|
|
10
|
+
domain: domain,
|
|
11
|
+
analyticsVersion: version
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
this.get(LicenseCall.licenseServerUrl, licensingRequest, callback);
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default LicenseCall;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
class Logger {
|
|
2
|
+
constructor(showLogs = false) {
|
|
3
|
+
this.showLogs = showLogs;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
setLogging(logging) {
|
|
7
|
+
this.showLogs = logging;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
isLogging() {
|
|
11
|
+
return this.showLogs;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
log = function(msg) {
|
|
15
|
+
if (!this.showLogs) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
console.log(msg);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
error = function(msg) {
|
|
23
|
+
if (!this.showLogs) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
console.error(msg);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
warning = function(msg) {
|
|
31
|
+
if (!this.showLogs) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
console.warn(msg);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const logger = new Logger();
|
|
40
|
+
export default logger;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/* global shaka */
|
|
2
|
+
/* global videojs */
|
|
3
|
+
/* global dashjs */
|
|
4
|
+
/* global Hls */
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Stateless. Functions that detect players somehow.
|
|
8
|
+
* @class
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
class PlayerDetector {
|
|
12
|
+
|
|
13
|
+
static isBitmovinVersionPre7 = function(player) {
|
|
14
|
+
if (PlayerDetector.isDashjs(player)) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (typeof player.getVersion === 'function') {
|
|
19
|
+
return player.getVersion() < '7';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return false;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
static isBitmovinVersion7Plus = function(player) {
|
|
26
|
+
if (typeof player.version === 'string') {
|
|
27
|
+
return player.version >= '7';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return false;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
static isVideoJs = function(player) {
|
|
34
|
+
if (typeof videojs === 'function') {
|
|
35
|
+
try {
|
|
36
|
+
if (videojs(player.id_) === player) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
} catch (err) {}
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static isShaka(player) {
|
|
45
|
+
|
|
46
|
+
if (!window.shaka) {
|
|
47
|
+
// Shaka is not defined installed (must be loaded before analytics module)
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
typeof shaka.Player === 'function' && player.constructor === shaka.Player
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static isDashjs(player) {
|
|
58
|
+
return typeof player.addABRCustomRule === 'function';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static isHlsjs(player) {
|
|
62
|
+
|
|
63
|
+
if (!window.Hls) {
|
|
64
|
+
// Hls.js is not defined installed (must be loaded before analytics module)
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
typeof window.Hls === 'function' && player.constructor === window.Hls
|
|
70
|
+
);
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export default PlayerDetector;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import HttpCall from './HttpCall';
|
|
2
|
+
import {ANALYTICS_BACKEND_BASE_URL} from './Settings';
|
|
3
|
+
|
|
4
|
+
class PlayerInitCall extends HttpCall{
|
|
5
|
+
static analyticsServerUrl = ANALYTICS_BACKEND_BASE_URL;
|
|
6
|
+
|
|
7
|
+
sendRequest = function(sample, callback) {
|
|
8
|
+
sample.event_family = 'player_init';
|
|
9
|
+
this.get(PlayerInitCall.analyticsServerUrl, sample, callback);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
sendRequestSynchronous = function(sample, callback) {
|
|
13
|
+
sample.event_family = 'player_init';
|
|
14
|
+
this.get(PlayerInitCall.analyticsServerUrl, sample, callback, false);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
getAnalyticsServerUrl = function() {
|
|
18
|
+
return PlayerInitCall.analyticsServerUrl;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default PlayerInitCall;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import HttpCall from './HttpCall';
|
|
2
|
+
import {ANALYTICS_BACKEND_BASE_URL} from './Settings';
|
|
3
|
+
|
|
4
|
+
class SessionCreationCall extends HttpCall{
|
|
5
|
+
static analyticsServerUrl = ANALYTICS_BACKEND_BASE_URL;
|
|
6
|
+
|
|
7
|
+
sendRequest = function(sample, callback) {
|
|
8
|
+
sample.event_family = 'session';
|
|
9
|
+
this.get(SessionCreationCall.analyticsServerUrl, sample, callback);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
sendRequestSynchronous = function(sample, callback) {
|
|
13
|
+
sample.event_family = 'session';
|
|
14
|
+
this.get(SessionCreationCall.analyticsServerUrl, sample, callback, false);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
getAnalyticsServerUrl = function() {
|
|
18
|
+
return SessionCreationCall.analyticsServerUrl;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default SessionCreationCall;
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
const validString = function(string) {
|
|
2
|
+
return (string != undefined && typeof string == 'string');
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
const validBoolean = function(boolean) {
|
|
6
|
+
return (boolean != undefined && typeof boolean == 'boolean');
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const validNumber = function(number) {
|
|
10
|
+
return (number != undefined && typeof number == 'number');
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const sanitizePath = function(path) {
|
|
14
|
+
return path.replace(/\/$/g, '');
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const calculateTime = function(time) {
|
|
18
|
+
time = time * 1000;
|
|
19
|
+
return Math.round(time);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const getCurrentTimestamp = function() {
|
|
23
|
+
return new Date().getTime();
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const getDurationFromTimestampToNow = function(timestamp) {
|
|
27
|
+
return getCurrentTimestamp() - timestamp;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const uuidv4 = function() {
|
|
31
|
+
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
|
|
32
|
+
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16).toUpperCase()
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const getCookie = function(cname) {
|
|
37
|
+
const name = cname + '=';
|
|
38
|
+
const ca = document.cookie.split(';');
|
|
39
|
+
let item = "";
|
|
40
|
+
for (let i = 0; i < ca.length; i++) {
|
|
41
|
+
let c = ca[i];
|
|
42
|
+
while (c.charAt(0) == ' ') {
|
|
43
|
+
c = c.substring(1);
|
|
44
|
+
}
|
|
45
|
+
if (c.indexOf(name) == 0) {
|
|
46
|
+
item = c.substring(name.length, c.length);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!item) {
|
|
51
|
+
try {
|
|
52
|
+
item = localStorage.getItem(cname);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
return "";
|
|
55
|
+
}
|
|
56
|
+
// check if localstorage has the item
|
|
57
|
+
let data = null;
|
|
58
|
+
if (item){
|
|
59
|
+
// try parsing the values as a JSON
|
|
60
|
+
try{
|
|
61
|
+
data = JSON.parse(item);
|
|
62
|
+
} catch (e) {
|
|
63
|
+
return "";
|
|
64
|
+
}
|
|
65
|
+
}else{
|
|
66
|
+
return "";
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// check if loaded data has expires if not return none
|
|
70
|
+
let expiresAt = null;
|
|
71
|
+
if (data.expires) {
|
|
72
|
+
expiresAt = new Date(data.expires);
|
|
73
|
+
}else{
|
|
74
|
+
return "";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Check if expiresAt is a valid dateTime object
|
|
78
|
+
if (Object.prototype.toString.call(expiresAt) === "[object Date]") {
|
|
79
|
+
// it is a date
|
|
80
|
+
if (isNaN(expiresAt)) {
|
|
81
|
+
// date object is not valid
|
|
82
|
+
return "";
|
|
83
|
+
} else {
|
|
84
|
+
// date object is valid
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
return "";
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Check if expires at is greater than the current time
|
|
91
|
+
if (expiresAt.getTime() > (new Date()).getTime()) {
|
|
92
|
+
// if data has value then return it else return ""
|
|
93
|
+
item = data.value ? data.value : "";
|
|
94
|
+
}else{
|
|
95
|
+
return "";
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// return read data
|
|
100
|
+
return item;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const setCookie = function(cname, expiry_mins=30, value=null) {
|
|
104
|
+
let date = new Date();
|
|
105
|
+
date.setTime(date.getTime() + (expiry_mins*60*1000));
|
|
106
|
+
let id = !value ? uuidv4() : value;
|
|
107
|
+
try {
|
|
108
|
+
document.cookie = cname+'=' + id +'; expires='+date.toUTCString()+'; path=/';
|
|
109
|
+
localStorage.setItem(cname, JSON.stringify({
|
|
110
|
+
expires: date.getTime(),
|
|
111
|
+
value: id
|
|
112
|
+
}));
|
|
113
|
+
} catch (error) {
|
|
114
|
+
}
|
|
115
|
+
return id;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const noOp = function() {
|
|
119
|
+
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const times = function (fn, times) {
|
|
123
|
+
let count = 0;
|
|
124
|
+
let retVal;
|
|
125
|
+
return function () {
|
|
126
|
+
if (count >= times) {
|
|
127
|
+
return retVal;
|
|
128
|
+
}
|
|
129
|
+
retVal = fn.apply(null, arguments);
|
|
130
|
+
count++;
|
|
131
|
+
return retVal;
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
const once = function (fn) {
|
|
136
|
+
return times(fn, 1);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const getHiddenProp = function() {
|
|
140
|
+
const prefixes = ['webkit','moz','ms','o'];
|
|
141
|
+
if ('hidden' in document) { return 'hidden'; }
|
|
142
|
+
for (let i = 0; i < prefixes.length; i++){
|
|
143
|
+
if ((prefixes[i] + 'Hidden') in document) {
|
|
144
|
+
return prefixes[i] + 'Hidden';
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return null;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const getCustomDataString = function(customData) {
|
|
151
|
+
if (typeof customData === 'object') {
|
|
152
|
+
return JSON.stringify(customData);
|
|
153
|
+
} else if (typeof customData === 'function') {
|
|
154
|
+
return getCustomDataString(customData());
|
|
155
|
+
} else if (typeof customData === 'undefined') {
|
|
156
|
+
return customData;
|
|
157
|
+
} else if (typeof customData !== 'string') {
|
|
158
|
+
return String(customData);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return customData;
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const jsonToQueryString = function(json) {
|
|
165
|
+
return '?' +
|
|
166
|
+
Object.keys(json).map(function(key) {
|
|
167
|
+
return encodeURIComponent(key) + '=' +
|
|
168
|
+
encodeURIComponent(json[key]);
|
|
169
|
+
}).join('&');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const currentDateTimeFormatString = function() {
|
|
173
|
+
const currentDateTime = new Date();
|
|
174
|
+
return currentDateTime.toISOString();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export default {
|
|
178
|
+
validString,
|
|
179
|
+
validBoolean,
|
|
180
|
+
validNumber,
|
|
181
|
+
sanitizePath,
|
|
182
|
+
calculateTime,
|
|
183
|
+
getCurrentTimestamp,
|
|
184
|
+
getDurationFromTimestampToNow,
|
|
185
|
+
uuidv4,
|
|
186
|
+
getCookie,
|
|
187
|
+
setCookie,
|
|
188
|
+
noOp,
|
|
189
|
+
times,
|
|
190
|
+
once,
|
|
191
|
+
getHiddenProp,
|
|
192
|
+
getCustomDataString,
|
|
193
|
+
jsonToQueryString,
|
|
194
|
+
currentDateTimeFormatString
|
|
195
|
+
};
|