@newrelic/video-core 3.1.0 → 3.2.0-beta-0
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/CHANGELOG.md +14 -2
- package/{LICENSE.txt → LICENSE} +2 -2
- package/README.md +22 -16
- package/THIRD_PARTY_NOTICES.md +5 -5
- package/package.json +5 -3
- package/src/agent.js +6 -0
- package/src/authConfiguration.js +138 -0
- package/src/chrono.js +78 -0
- package/src/constants.js +43 -0
- package/src/core.js +100 -0
- package/src/emitter.js +81 -0
- package/src/eventAggregator.js +66 -0
- package/src/harvester.js +171 -0
- package/src/index.js +22 -0
- package/src/log.js +323 -0
- package/src/recordEvent.js +68 -0
- package/src/tracker.js +281 -0
- package/src/utils.js +101 -0
- package/src/videotracker.js +1060 -0
- package/src/videotrackerstate.js +574 -0
- package/dist/cjs/index.js +0 -1
- package/dist/cjs/index.js.LICENSE.txt +0 -6
- package/dist/esm/index.js +0 -1
- package/dist/esm/index.js.LICENSE.txt +0 -6
- package/dist/umd/nrvideo.min.js +0 -1
- package/dist/umd/nrvideo.min.js.LICENSE.txt +0 -6
package/CHANGELOG.md
CHANGED
|
@@ -2,15 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [3.2.1] - 2025/07/30
|
|
6
|
+
|
|
7
|
+
### Breaking Change
|
|
8
|
+
|
|
9
|
+
- Decoupled from browser agent, now uses its own harvesting system for independent data collection.
|
|
10
|
+
|
|
11
|
+
## [3.1.1] - 2025/06/09
|
|
12
|
+
|
|
13
|
+
### Fix
|
|
14
|
+
|
|
15
|
+
- Updated event type for `AD_ERROR` to `VideoErrorAction`
|
|
16
|
+
|
|
5
17
|
## [3.1.0] - 2025-05-26
|
|
6
18
|
|
|
7
19
|
### Enhancements
|
|
8
20
|
|
|
9
|
-
|
|
21
|
+
- **Publishing to npm:** The package can now be published to npm, making it easily accessible.
|
|
10
22
|
|
|
11
23
|
### Build
|
|
12
24
|
|
|
13
|
-
|
|
25
|
+
- **Distribution Formats:** Added `cjs`, `esm`, and `umd` builds to the `dist` folder, ensuring compatibility with CommonJS, ES Modules, and UMD module formats.
|
|
14
26
|
|
|
15
27
|
## [3.0.0] - 2025/02/20
|
|
16
28
|
|
package/{LICENSE.txt → LICENSE}
RENAMED
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
same "printed page" as the copyright notice for easier
|
|
187
187
|
identification within third-party archives.
|
|
188
188
|
|
|
189
|
-
Copyright
|
|
189
|
+
Copyright New Relic, Inc. All rights reserved.
|
|
190
190
|
|
|
191
191
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
192
|
you may not use this file except in compliance with the License.
|
|
@@ -198,4 +198,4 @@
|
|
|
198
198
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
199
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
200
|
See the License for the specific language governing permissions and
|
|
201
|
-
limitations under the License.
|
|
201
|
+
limitations under the License.
|
package/README.md
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
# New Relic Video Core - JavaScript
|
|
4
4
|
|
|
5
|
+
> **⚠️ BETA VERSION NOTICE**
|
|
6
|
+
> This version is currently in **beta phase** and is under active development. Features and APIs may change without notice. Use with caution in production environments and expect potential breaking changes in future releases.
|
|
7
|
+
|
|
5
8
|
The New Relic video tracking core library is the base for all video trackers in the browser platform. It contains the classes and core mechanisms used by the player specific trackers.
|
|
6
9
|
It segregates the events into different event types based on action, such as video-related events going to `VideoAction`, ad-related events to `VideoAdAction`, errors to `VideoErrorAction`, and custom actions to `VideoCustomAction`.
|
|
7
10
|
|
|
@@ -36,10 +39,20 @@ Add **scripts** inside `dist` folder to your page.
|
|
|
36
39
|
`nrvideo` provides a class called `VideoTracker` that will serve as an interface with
|
|
37
40
|
_Browser Agent_, allowing you to manage and send events to New Relic.
|
|
38
41
|
|
|
39
|
-
First
|
|
42
|
+
First, configure the authentication options and initialize a tracker:
|
|
40
43
|
|
|
41
44
|
```javascript
|
|
42
|
-
|
|
45
|
+
const options = {
|
|
46
|
+
info: {
|
|
47
|
+
beacon: "your-beacon-url.nr-data.net",
|
|
48
|
+
errorBeacon: "your-beacon-url.nr-data.net",
|
|
49
|
+
licenseKey: "your-license-key",
|
|
50
|
+
applicationID: "your-application-id",
|
|
51
|
+
sa: 1,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const tracker = new VideoTracker(player, options);
|
|
43
56
|
```
|
|
44
57
|
|
|
45
58
|
Once the tracker is added, any event it emits will be sent to New Relic and processed by the following functions:
|
|
@@ -51,27 +64,14 @@ tracker.sendVideoErrorAction("ErrorEvent", { data: "error-test" });
|
|
|
51
64
|
tracker.sendVideoCustomAction("CustomEvent", { data: "custom-test" });
|
|
52
65
|
```
|
|
53
66
|
|
|
54
|
-
Of course, you may want to use built-in events for video. Luckily for you, this core library
|
|
55
|
-
provides an easy way of sending video-related content, using `tracker.sendXXXXX` methods.
|
|
56
|
-
|
|
57
|
-
```javascript
|
|
58
|
-
tracker.sendRequest(); // Will send CONTENT_REQUEST
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Search for `Tracker#sendXXXX` events in the documentation to read more about it.
|
|
62
|
-
|
|
63
67
|
## Data Model
|
|
64
68
|
|
|
65
|
-
To understand which actions and attributes are captured and emitted by the tracker under different event types, see [DataModel.md](
|
|
69
|
+
To understand which actions and attributes are captured and emitted by the tracker under different event types, see [DataModel.md](DATAMODEL.md).
|
|
66
70
|
|
|
67
71
|
## Documentation
|
|
68
72
|
|
|
69
73
|
All classes are documented using autodocs. The documents, generated with [jsdoc](https://github.com/jsdoc/jsdoc), can be found in the `documentation` directory of the current repo.
|
|
70
74
|
|
|
71
|
-
# Open source license
|
|
72
|
-
|
|
73
|
-
This project is distributed under the [Apache 2 license](LICENSE).
|
|
74
|
-
|
|
75
75
|
# Support
|
|
76
76
|
|
|
77
77
|
New Relic has open-sourced this project. This project is provided AS-IS WITHOUT WARRANTY OR DEDICATED SUPPORT. Issues and contributions should be reported to the project here on GitHub.
|
|
@@ -93,3 +93,9 @@ Issues and enhancement requests can be submitted in the [Issues tab of this repo
|
|
|
93
93
|
Contributions are encouraged! If you submit an enhancement request, we'll invite you to contribute the change yourself. Please review our [Contributors Guide](CONTRIBUTING.md).
|
|
94
94
|
|
|
95
95
|
Keep in mind that when you submit your pull request, you'll need to sign the CLA via the click-through using CLA-Assistant. If you'd like to execute our corporate CLA, or if you have any questions, please drop us an email at opensource+videoagent@newrelic.com.
|
|
96
|
+
|
|
97
|
+
# License
|
|
98
|
+
|
|
99
|
+
This project is distributed under the [Apache 2.0](https://apache.org/licenses/LICENSE-2.0.txt) License.
|
|
100
|
+
|
|
101
|
+
The video-core also uses source code from third-party libraries. Full details on which libraries are used and the terms under which they are licensed can be found in the [third-party notices document](THIRD_PARTY_NOTICES.md).
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -45,7 +45,7 @@ code, the source code can be found at [https://github.com/newrelic/video-core-js
|
|
|
45
45
|
|
|
46
46
|
### @babel/core
|
|
47
47
|
|
|
48
|
-
This product includes source derived from [@babel/core](https://github.com/babel/babel) ([v7.
|
|
48
|
+
This product includes source derived from [@babel/core](https://github.com/babel/babel) ([v7.27.4](https://github.com/babel/babel/tree/v7.27.4)), distributed under the [MIT License](https://github.com/babel/babel/blob/v7.27.4/LICENSE):
|
|
49
49
|
|
|
50
50
|
```
|
|
51
51
|
MIT License
|
|
@@ -75,7 +75,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
75
75
|
|
|
76
76
|
### @babel/plugin-transform-modules-commonjs
|
|
77
77
|
|
|
78
|
-
This product includes source derived from [@babel/plugin-transform-modules-commonjs](https://github.com/babel/babel) ([v7.
|
|
78
|
+
This product includes source derived from [@babel/plugin-transform-modules-commonjs](https://github.com/babel/babel) ([v7.27.1](https://github.com/babel/babel/tree/v7.27.1)), distributed under the [MIT License](https://github.com/babel/babel/blob/v7.27.1/LICENSE):
|
|
79
79
|
|
|
80
80
|
```
|
|
81
81
|
MIT License
|
|
@@ -105,7 +105,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
105
105
|
|
|
106
106
|
### @babel/preset-env
|
|
107
107
|
|
|
108
|
-
This product includes source derived from [@babel/preset-env](https://github.com/babel/babel) ([v7.
|
|
108
|
+
This product includes source derived from [@babel/preset-env](https://github.com/babel/babel) ([v7.27.2](https://github.com/babel/babel/tree/v7.27.2)), distributed under the [MIT License](https://github.com/babel/babel/blob/v7.27.2/LICENSE):
|
|
109
109
|
|
|
110
110
|
```
|
|
111
111
|
MIT License
|
|
@@ -135,7 +135,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
135
135
|
|
|
136
136
|
### @babel/register
|
|
137
137
|
|
|
138
|
-
This product includes source derived from [@babel/register](https://github.com/babel/babel) ([v7.
|
|
138
|
+
This product includes source derived from [@babel/register](https://github.com/babel/babel) ([v7.27.1](https://github.com/babel/babel/tree/v7.27.1)), distributed under the [MIT License](https://github.com/babel/babel/blob/v7.27.1/LICENSE):
|
|
139
139
|
|
|
140
140
|
```
|
|
141
141
|
MIT License
|
|
@@ -851,7 +851,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
851
851
|
|
|
852
852
|
### webpack
|
|
853
853
|
|
|
854
|
-
This product includes source derived from [webpack](https://github.com/webpack/webpack) ([v5.
|
|
854
|
+
This product includes source derived from [webpack](https://github.com/webpack/webpack) ([v5.99.9](https://github.com/webpack/webpack/tree/v5.99.9)), distributed under the [MIT License](https://github.com/webpack/webpack/blob/v5.99.9/LICENSE):
|
|
855
855
|
|
|
856
856
|
```
|
|
857
857
|
Copyright JS Foundation and other contributors
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@newrelic/video-core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0-beta-0",
|
|
4
4
|
"description": "New Relic video tracking core library",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"contributors": [
|
|
24
24
|
"Andreu Santarén Llop"
|
|
25
25
|
],
|
|
26
|
-
"license": "
|
|
26
|
+
"license": "Apache-2.0",
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@babel/core": "^7.24.5",
|
|
29
29
|
"@babel/plugin-transform-modules-commonjs": "^7.24.1",
|
|
@@ -45,11 +45,13 @@
|
|
|
45
45
|
"files": [
|
|
46
46
|
"THIRD_PARTY_NOTICES.md",
|
|
47
47
|
"dist",
|
|
48
|
+
"src",
|
|
48
49
|
"CHANGELOG.md",
|
|
50
|
+
"LICENSE",
|
|
49
51
|
"README.md",
|
|
50
52
|
"!test"
|
|
51
53
|
],
|
|
52
|
-
|
|
54
|
+
"publishConfig": {
|
|
53
55
|
"access": "public"
|
|
54
56
|
}
|
|
55
57
|
}
|
package/src/agent.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { NRVideoEventAggregator } from "./eventAggregator.js";
|
|
2
|
+
import { NRVideoHarvester } from "./harvester.js";
|
|
3
|
+
|
|
4
|
+
export const customEventAggregator = new NRVideoEventAggregator();
|
|
5
|
+
const harvester = new NRVideoHarvester(customEventAggregator);
|
|
6
|
+
harvester.startTimer();
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import Constants from "./constants";
|
|
2
|
+
|
|
3
|
+
const { COLLECTOR } = Constants;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Validates and initializes New Relic video tracking information.
|
|
7
|
+
* @param {object} info - The options object containing authentication information.
|
|
8
|
+
* @param {string} info.licenseKey - The New Relic license key.
|
|
9
|
+
* @param {string} [info.appName] - The name of the application (required if no applicationID).
|
|
10
|
+
* @param {string} [info.region] - The region for the New Relic collector (required if no beacon).
|
|
11
|
+
* @param {string} [info.beacon] - Custom beacon URL (optional, overrides region-based beacon).
|
|
12
|
+
* @param {string} [info.sa] - Security attributes (optional).
|
|
13
|
+
* @param {string} [info.applicationID] - Application ID for beacon-based configuration (optional).
|
|
14
|
+
* @returns {boolean} True if configuration was set successfully, false otherwise.
|
|
15
|
+
* @throws {Error} Throws error for invalid configuration parameters.
|
|
16
|
+
*/
|
|
17
|
+
export function setAuthConfig(info) {
|
|
18
|
+
try {
|
|
19
|
+
// Input validation
|
|
20
|
+
if (!info || typeof info !== "object" || Array.isArray(info)) {
|
|
21
|
+
throw new Error("setAuthConfig: info parameter must be a valid object");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (isAuthorised(info)) {
|
|
25
|
+
const { licenseKey, appName, region, beacon, sa, applicationID } = info;
|
|
26
|
+
|
|
27
|
+
// Initialize NRVIDEO global object
|
|
28
|
+
window.NRVIDEO = window.NRVIDEO || {};
|
|
29
|
+
|
|
30
|
+
// Determine beacon URL with fallback
|
|
31
|
+
let beaconUrl = beacon;
|
|
32
|
+
if (!beaconUrl && region) {
|
|
33
|
+
if (!COLLECTOR[region]) {
|
|
34
|
+
throw new Error(
|
|
35
|
+
`setAuthConfig: Invalid region '${region}'. Valid regions: ${Object.keys(
|
|
36
|
+
COLLECTOR
|
|
37
|
+
).join(", ")}`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
beaconUrl = COLLECTOR[region];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
window.NRVIDEO.info = {
|
|
44
|
+
beacon: beaconUrl,
|
|
45
|
+
licenseKey,
|
|
46
|
+
applicationID: applicationID || null,
|
|
47
|
+
appName: appName || null,
|
|
48
|
+
sa: sa || 0,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return true;
|
|
52
|
+
} else {
|
|
53
|
+
const validationError = getValidationError(info);
|
|
54
|
+
throw new Error(`setAuthConfig: ${validationError}`);
|
|
55
|
+
}
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error("setAuthConfig:", error.message);
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Checks if the provided information contains valid authentication parameters.
|
|
64
|
+
* @param {object} info - The options object.
|
|
65
|
+
* @returns {boolean} True if authorized, false otherwise.
|
|
66
|
+
*/
|
|
67
|
+
function isAuthorised(info) {
|
|
68
|
+
if (!info || typeof info !== "object") {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const { licenseKey, appName, region, applicationID, beacon } = info;
|
|
73
|
+
|
|
74
|
+
// License key is always required
|
|
75
|
+
if (
|
|
76
|
+
!licenseKey ||
|
|
77
|
+
typeof licenseKey !== "string" ||
|
|
78
|
+
licenseKey.trim().length === 0
|
|
79
|
+
) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Two valid configuration modes:
|
|
84
|
+
// 1. applicationID + beacon (for direct beacon configuration)
|
|
85
|
+
// 2. appName + region (for region-based beacon resolution)
|
|
86
|
+
if (applicationID) {
|
|
87
|
+
return !!(beacon && typeof beacon === "string" && beacon.trim().length > 0);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return !!(
|
|
91
|
+
appName &&
|
|
92
|
+
typeof appName === "string" &&
|
|
93
|
+
appName.trim().length > 0 &&
|
|
94
|
+
region &&
|
|
95
|
+
typeof region === "string" &&
|
|
96
|
+
region.trim().length > 0
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Provides detailed validation error message for debugging.
|
|
102
|
+
* @param {object} info - The options object.
|
|
103
|
+
* @returns {string} Detailed error message.
|
|
104
|
+
*/
|
|
105
|
+
function getValidationError(info) {
|
|
106
|
+
if (!info || typeof info !== "object") {
|
|
107
|
+
return "info parameter must be a valid object";
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const { licenseKey, appName, region, applicationID, beacon } = info;
|
|
111
|
+
|
|
112
|
+
if (
|
|
113
|
+
!licenseKey ||
|
|
114
|
+
typeof licenseKey !== "string" ||
|
|
115
|
+
licenseKey.trim().length === 0
|
|
116
|
+
) {
|
|
117
|
+
return "licenseKey is required and must be a non-empty string";
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (applicationID) {
|
|
121
|
+
if (!beacon || typeof beacon !== "string" || beacon.trim().length === 0) {
|
|
122
|
+
return "beacon URL is required when using applicationID";
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
if (
|
|
126
|
+
!appName ||
|
|
127
|
+
typeof appName !== "string" ||
|
|
128
|
+
appName.trim().length === 0
|
|
129
|
+
) {
|
|
130
|
+
return "appName is required when not using applicationID";
|
|
131
|
+
}
|
|
132
|
+
if (!region || typeof region !== "string" || region.trim().length === 0) {
|
|
133
|
+
return "region is required when not using applicationID";
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return "configuration validation failed";
|
|
138
|
+
}
|
package/src/chrono.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This class calculates time lapses between two points on time.
|
|
3
|
+
*/
|
|
4
|
+
class Chrono {
|
|
5
|
+
/**
|
|
6
|
+
* Constructor
|
|
7
|
+
*/
|
|
8
|
+
constructor() {
|
|
9
|
+
this.reset();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Reset chrono values. */
|
|
13
|
+
reset() {
|
|
14
|
+
/** Start time */
|
|
15
|
+
this.startTime = 0;
|
|
16
|
+
|
|
17
|
+
/** Stop time */
|
|
18
|
+
this.stopTime = 0;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* If you set an offset in a chrono, its value will be added getDeltaTime and stop.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* let chrono = new Chrono()
|
|
25
|
+
* chrono.offset = 500
|
|
26
|
+
* chrono.start()
|
|
27
|
+
* process.sleep(500)
|
|
28
|
+
* chrono.stop() // Will return 1000
|
|
29
|
+
*
|
|
30
|
+
* @type {number}
|
|
31
|
+
*/
|
|
32
|
+
this.offset = 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Returns the time between start() and the last stop() in ms. Returns null if start wasn't
|
|
37
|
+
* called.
|
|
38
|
+
* @return {(number|null)} Time lapse in ms.
|
|
39
|
+
*/
|
|
40
|
+
getDeltaTime() {
|
|
41
|
+
if (this.startTime) {
|
|
42
|
+
return this.offset + (new Date().getTime() - this.startTime);
|
|
43
|
+
} else {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Starts the chrono.
|
|
50
|
+
*/
|
|
51
|
+
start() {
|
|
52
|
+
this.startTime = new Date().getTime();
|
|
53
|
+
this.stopTime = 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Stops the timer and returns delta time.
|
|
58
|
+
* @return {(number|null)} Returns the delta time
|
|
59
|
+
*/
|
|
60
|
+
stop() {
|
|
61
|
+
this.stopTime = new Date().getTime();
|
|
62
|
+
return this.getDeltaTime();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Creates a copy of the chrono.
|
|
67
|
+
* @returns {Chrono} Cloned chrono
|
|
68
|
+
*/
|
|
69
|
+
clone() {
|
|
70
|
+
var chrono = new Chrono();
|
|
71
|
+
chrono.startTime = this.startTime;
|
|
72
|
+
chrono.stopTime = this.stopTime;
|
|
73
|
+
chrono.offset = this.offset;
|
|
74
|
+
return chrono;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export default Chrono;
|
package/src/constants.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants for the library.
|
|
3
|
+
* @class Constants
|
|
4
|
+
* @static
|
|
5
|
+
*/
|
|
6
|
+
class Constants {}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Enum for types/positions of ads.
|
|
10
|
+
* @example var type = Constants.AdPositions.PRE
|
|
11
|
+
* @enum {String}
|
|
12
|
+
*/
|
|
13
|
+
Constants.AdPositions = {
|
|
14
|
+
/** For ads shown before the content. */
|
|
15
|
+
PRE: "pre",
|
|
16
|
+
/** For ads shown during the content. */
|
|
17
|
+
MID: "mid",
|
|
18
|
+
/** For ads shown after the content. */
|
|
19
|
+
POST: "post",
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
Constants.INTERVAL = 10000;
|
|
23
|
+
Constants.MAX_EVENTS_PER_BATCH = 1000;
|
|
24
|
+
Constants.MAX_PAYLOAD_SIZE = 1; // 1mb
|
|
25
|
+
Constants.MAX_BEACON_SIZE = 0.0625; // 64kb
|
|
26
|
+
Constants.MAX_EVENT_SIZE = 0.0625; // 64kb
|
|
27
|
+
Constants.VALID_EVENT_TYPES = [
|
|
28
|
+
"VideoAction",
|
|
29
|
+
"VideoAdAction",
|
|
30
|
+
"VideoErrorAction",
|
|
31
|
+
"VideoCustomAction",
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
Constants.COLLECTOR = {
|
|
35
|
+
US: "bam-cell.nr-data.net",
|
|
36
|
+
EU: "bam.eu01.nr-data.net",
|
|
37
|
+
Stage: "staging-bam-cell.nr-data.net",
|
|
38
|
+
GOV: "gov-bam.nr-data.net",
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// "bam.nr-data.net",
|
|
42
|
+
|
|
43
|
+
export default Constants;
|
package/src/core.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import Log from "./log";
|
|
2
|
+
import { recordEvent } from "./recordEvent";
|
|
3
|
+
import { setAuthConfig } from "./authConfiguration";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Static class that sums up core functionalities of the library.
|
|
7
|
+
* @static
|
|
8
|
+
*/
|
|
9
|
+
class Core {
|
|
10
|
+
/**
|
|
11
|
+
* Add a tracker to the system. Trackers added will start reporting its events to NR's backend.
|
|
12
|
+
*
|
|
13
|
+
* @param {(Emitter|Tracker)} tracker Tracker instance to add.
|
|
14
|
+
*/
|
|
15
|
+
static addTracker(tracker, options) {
|
|
16
|
+
setAuthConfig(options.info);
|
|
17
|
+
if (tracker.on && tracker.emit) {
|
|
18
|
+
trackers.push(tracker);
|
|
19
|
+
tracker.on("*", eventHandler);
|
|
20
|
+
if (typeof tracker.trackerInit == "function") {
|
|
21
|
+
tracker.trackerInit();
|
|
22
|
+
}
|
|
23
|
+
} else {
|
|
24
|
+
Log.error("Tried to load a non-tracker.", tracker);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Disposes and remove given tracker. Removes its listeners.
|
|
30
|
+
*
|
|
31
|
+
* @param {Tracker} tracker Tracker to remove.
|
|
32
|
+
*/
|
|
33
|
+
static removeTracker(tracker) {
|
|
34
|
+
tracker.off("*", eventHandler);
|
|
35
|
+
tracker.dispose();
|
|
36
|
+
let index = trackers.indexOf(tracker);
|
|
37
|
+
if (index !== -1) trackers.splice(index, 1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Returns the array of trackers.
|
|
42
|
+
*
|
|
43
|
+
* @returns {Tracker[]} Array of trackers.
|
|
44
|
+
*/
|
|
45
|
+
static getTrackers() {
|
|
46
|
+
return trackers;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static send(eventType, actionName, data) {
|
|
50
|
+
data["timeSinceLoad"] = window.performance.now() / 1000;
|
|
51
|
+
recordEvent(eventType, { actionName, ...data });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Sends an error event. This may be used for external errors launched by the app, the network or
|
|
56
|
+
* any external factor. Note that errors within the player are normally reported with
|
|
57
|
+
* tracker.sendError, so this method should not be used to report those.
|
|
58
|
+
*
|
|
59
|
+
* @param {object} att attributes to be sent along the error.
|
|
60
|
+
*/
|
|
61
|
+
static sendError(att) {
|
|
62
|
+
Core.send("ERROR", att);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let trackers = [];
|
|
67
|
+
let isErrorShown = false;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Logs and sends given event.
|
|
71
|
+
*
|
|
72
|
+
* @private
|
|
73
|
+
* @param {Event} e Event
|
|
74
|
+
*/
|
|
75
|
+
function eventHandler(e) {
|
|
76
|
+
let data = cleanData(e.data);
|
|
77
|
+
if (Log.level <= Log.Levels.DEBUG) {
|
|
78
|
+
Log.notice("Sent", e.type, data);
|
|
79
|
+
} else {
|
|
80
|
+
Log.notice("Sent", e.type);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
Core.send(e.eventType, e.type, data);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Cleans given object, removing all items with value === null.
|
|
88
|
+
* @private
|
|
89
|
+
* @param {Object} data Data to clean
|
|
90
|
+
* @returns {Object} Cleaned object
|
|
91
|
+
*/
|
|
92
|
+
function cleanData(data) {
|
|
93
|
+
let ret = {};
|
|
94
|
+
for (let i in data) {
|
|
95
|
+
if (data[i] !== null && typeof data[i] !== "undefined") ret[i] = data[i];
|
|
96
|
+
}
|
|
97
|
+
return ret;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export default Core;
|
package/src/emitter.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This base class implements a basic behavior of listeners and events. Extend this object to have
|
|
3
|
+
* this feature built-in inside your classes.
|
|
4
|
+
*
|
|
5
|
+
* @class Emitter
|
|
6
|
+
*/
|
|
7
|
+
class Emitter {
|
|
8
|
+
/**
|
|
9
|
+
* Sets a listener to a given event. Use {@link emit} to trigger those events.
|
|
10
|
+
* Pass '*' to listen ALL events.
|
|
11
|
+
*
|
|
12
|
+
* @param {string} event Name of the event.
|
|
13
|
+
* @param {function} callback Callback of the event. Receives event and data.
|
|
14
|
+
* @return this
|
|
15
|
+
*/
|
|
16
|
+
on(event, callback) {
|
|
17
|
+
this._listeners = this._listeners || {};
|
|
18
|
+
if (typeof callback === "function") {
|
|
19
|
+
this._listeners[event] = this._listeners[event] || [];
|
|
20
|
+
this._listeners[event].push(callback);
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Removes given callback from the listeners of this object.
|
|
27
|
+
*
|
|
28
|
+
* @param {string} event Name of the event.
|
|
29
|
+
* @param {function} callback Callback of the event.
|
|
30
|
+
* @return this
|
|
31
|
+
*/
|
|
32
|
+
off(event, callback) {
|
|
33
|
+
this._listeners = this._listeners || {};
|
|
34
|
+
|
|
35
|
+
if (this._listeners[event]) {
|
|
36
|
+
var index = this._listeners[event].indexOf(callback);
|
|
37
|
+
if (index !== -1) {
|
|
38
|
+
this._listeners[event].splice(index, 1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Emits given event, triggering all the associated callbacks.
|
|
46
|
+
*
|
|
47
|
+
* @param {string} event Name of the event.
|
|
48
|
+
* @param {object} [data] Custom data to be sent to the callbacks.
|
|
49
|
+
* @return this
|
|
50
|
+
*/
|
|
51
|
+
emit(eventType, event, data) {
|
|
52
|
+
this._listeners = this._listeners || {};
|
|
53
|
+
data = data || {};
|
|
54
|
+
|
|
55
|
+
if (Array.isArray(this._listeners[event])) {
|
|
56
|
+
this._listeners[event].forEach((callback) => {
|
|
57
|
+
callback.call(this, {
|
|
58
|
+
eventType,
|
|
59
|
+
type: event,
|
|
60
|
+
data: data,
|
|
61
|
+
target: this,
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (Array.isArray(this._listeners["*"])) {
|
|
67
|
+
this._listeners["*"].forEach((callback) => {
|
|
68
|
+
callback.call(this, {
|
|
69
|
+
eventType,
|
|
70
|
+
type: event,
|
|
71
|
+
data: data,
|
|
72
|
+
target: this,
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export default Emitter;
|