Socket
Socket
Sign inDemoInstall

@folklore/tracking

Package Overview
Dependencies
Maintainers
6
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@folklore/tracking - npm Package Compare versions

Comparing version 0.0.20 to 0.0.21

143

dist/cjs.js

@@ -5,2 +5,3 @@ 'use strict';

var uuid = require('uuid');
var React = require('react');

@@ -16,3 +17,2 @@ var jsxRuntime = require('react/jsx-runtime');

/* eslint-disable class-methods-use-this */
class Tracking {

@@ -59,3 +59,3 @@ constructor() {

if (!paused && this.pending.length > 0) {
this.push(...this.pending);
this.pushNow(...this.pending);
this.pending = [];

@@ -74,19 +74,19 @@ }

push() {
const {
dataLayer = null
} = this.options;
if (dataLayer === null || this.disabled) {
return;
}
if (this.paused) {
if (this.paused && !this.disabled) {
this.pending.push(...arguments);
return;
}
dataLayer.push(...arguments);
this.pushNow(...arguments);
}
pushEvent(eventName, data) {
this.push({
event: eventName,
eventId: uuid.v4(),
...data
});
}
trackEvent(category, action) {
let label = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
let value = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
this.push({
event: 'eventInteraction',
this.pushEvent('eventInteraction', {
eventCategory: category,

@@ -100,4 +100,3 @@ eventAction: action,

let target = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
this.push({
event: 'socialInteraction',
this.pushEvent('socialInteraction', {
socialNetwork: network,

@@ -108,2 +107,26 @@ socialAction: action,

}
trackVideo(action) {
let {
platform = null,
id = null,
url,
title = null,
duration = null,
currentTime = null,
thumbnail = null
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
this.pushEvent('eventInteraction', {
eventCategory: 'Video',
eventAction: action,
eventLabel: `${platform !== null ? `${platform}: ` : ''}${title || document.title}${id !== null ? ` (${id})` : ''}`,
videoPlatform: platform,
videoId: id,
videoUrl: url,
videoTitle: title,
videoDuration: duration,
videoCurrentTime: currentTime !== null ? Math.round(currentTime) : null,
videoProgress: currentTime !== null && duration !== null && duration > 0 ? Math.round(currentTime / duration * 100) : null,
videoThumbnail: thumbnail
});
}
getSocialTarget() {

@@ -169,2 +192,93 @@ return typeof window !== 'undefined' ? `${window.location.protocol}//${window.location.host}` : null;

function useVideoTracking(player, params) {
if (player === null) {
return;
}
const {
provider,
id,
url,
title = null,
thumbnail = null,
progressSteps = [0.1, 0.25, 0.5, 0.75, 0.9]
} = params || {};
const tracking = useTracking$1();
const progressTrackedRef = React.useRef({});
const {
playing = false,
paused = false,
ended = false,
currentTime = false,
duration = null
} = player;
const getVideoMetadata = React.useCallback(metadata => {
let metadataTitle = null;
try {
metadataTitle = title !== null ? decodeURIComponent(title).replace(/[+]+/gi, ' ') : null;
} catch (e) {
console.log('error decoding title', e); // eslint-disable-line
}
return {
platform: provider,
id,
url,
title: metadataTitle,
duration: duration || 0,
thumbnail,
...metadata
};
}, [provider, id, title, url, duration, thumbnail]);
React.useEffect(() => {
if (playing) {
tracking.trackVideo('play', getVideoMetadata({
currentTime
}));
}
}, [playing]);
React.useEffect(() => {
if (paused) {
tracking.trackVideo('pause', getVideoMetadata({
currentTime
}));
}
}, [paused]);
React.useEffect(() => {
if (ended) {
tracking.trackVideo('end', getVideoMetadata({
currentTime
}));
}
}, [ended]);
React.useEffect(() => {
if (currentTime === null || currentTime <= 0 || duration === null || duration <= 0 || progressSteps === null || progressSteps.length === 0) {
return;
}
const progress = currentTime / duration;
const stepsToTrack = progressSteps.filter(step => progress > step && (typeof progressTrackedRef.current[id] === 'undefined' || typeof progressTrackedRef.current[id][step] === 'undefined'));
stepsToTrack.forEach(step => {
// console.log(
// Math.round(step * 100, 10),
// getVideoMetadata({
// currentTime,
// }),
// );
tracking.trackVideo(`progress ${Math.round(step * 100, 10)}%`, getVideoMetadata({
currentTime
}));
});
if (stepsToTrack !== null && stepsToTrack.length > 0) {
progressTrackedRef.current = {
...progressTrackedRef.current,
[id]: {
...progressTrackedRef.current[id],
...stepsToTrack.reduce((stepsMap, step) => ({
...stepsMap,
[step]: true
}), {})
}
};
}
}, [currentTime, progressTrackedRef.current, id]);
}
exports.Tracking = Tracking$1;

@@ -175,2 +289,3 @@ exports.TrackingContainer = TrackingContainer;

exports.useTracking = useTracking$1;
exports.useVideoTracking = useVideoTracking;
exports.withTracking = withTracking$1;

@@ -1,2 +0,3 @@

import React, { useContext, useMemo, useEffect } from 'react';
import { v4 } from 'uuid';
import React, { useContext, useMemo, useEffect, useRef, useCallback } from 'react';
import { jsx } from 'react/jsx-runtime';

@@ -6,3 +7,2 @@ import PropTypes from 'prop-types';

/* eslint-disable class-methods-use-this */
class Tracking {

@@ -49,3 +49,3 @@ constructor() {

if (!paused && this.pending.length > 0) {
this.push(...this.pending);
this.pushNow(...this.pending);
this.pending = [];

@@ -64,19 +64,19 @@ }

push() {
const {
dataLayer = null
} = this.options;
if (dataLayer === null || this.disabled) {
return;
}
if (this.paused) {
if (this.paused && !this.disabled) {
this.pending.push(...arguments);
return;
}
dataLayer.push(...arguments);
this.pushNow(...arguments);
}
pushEvent(eventName, data) {
this.push({
event: eventName,
eventId: v4(),
...data
});
}
trackEvent(category, action) {
let label = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
let value = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
this.push({
event: 'eventInteraction',
this.pushEvent('eventInteraction', {
eventCategory: category,

@@ -90,4 +90,3 @@ eventAction: action,

let target = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
this.push({
event: 'socialInteraction',
this.pushEvent('socialInteraction', {
socialNetwork: network,

@@ -98,2 +97,26 @@ socialAction: action,

}
trackVideo(action) {
let {
platform = null,
id = null,
url,
title = null,
duration = null,
currentTime = null,
thumbnail = null
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
this.pushEvent('eventInteraction', {
eventCategory: 'Video',
eventAction: action,
eventLabel: `${platform !== null ? `${platform}: ` : ''}${title || document.title}${id !== null ? ` (${id})` : ''}`,
videoPlatform: platform,
videoId: id,
videoUrl: url,
videoTitle: title,
videoDuration: duration,
videoCurrentTime: currentTime !== null ? Math.round(currentTime) : null,
videoProgress: currentTime !== null && duration !== null && duration > 0 ? Math.round(currentTime / duration * 100) : null,
videoThumbnail: thumbnail
});
}
getSocialTarget() {

@@ -159,2 +182,93 @@ return typeof window !== 'undefined' ? `${window.location.protocol}//${window.location.host}` : null;

export { Tracking$1 as Tracking, TrackingContainer, TrackingContext$1 as TrackingContext, Tracking$1 as default, useTracking$1 as useTracking, withTracking$1 as withTracking };
function useVideoTracking(player, params) {
if (player === null) {
return;
}
const {
provider,
id,
url,
title = null,
thumbnail = null,
progressSteps = [0.1, 0.25, 0.5, 0.75, 0.9]
} = params || {};
const tracking = useTracking$1();
const progressTrackedRef = useRef({});
const {
playing = false,
paused = false,
ended = false,
currentTime = false,
duration = null
} = player;
const getVideoMetadata = useCallback(metadata => {
let metadataTitle = null;
try {
metadataTitle = title !== null ? decodeURIComponent(title).replace(/[+]+/gi, ' ') : null;
} catch (e) {
console.log('error decoding title', e); // eslint-disable-line
}
return {
platform: provider,
id,
url,
title: metadataTitle,
duration: duration || 0,
thumbnail,
...metadata
};
}, [provider, id, title, url, duration, thumbnail]);
useEffect(() => {
if (playing) {
tracking.trackVideo('play', getVideoMetadata({
currentTime
}));
}
}, [playing]);
useEffect(() => {
if (paused) {
tracking.trackVideo('pause', getVideoMetadata({
currentTime
}));
}
}, [paused]);
useEffect(() => {
if (ended) {
tracking.trackVideo('end', getVideoMetadata({
currentTime
}));
}
}, [ended]);
useEffect(() => {
if (currentTime === null || currentTime <= 0 || duration === null || duration <= 0 || progressSteps === null || progressSteps.length === 0) {
return;
}
const progress = currentTime / duration;
const stepsToTrack = progressSteps.filter(step => progress > step && (typeof progressTrackedRef.current[id] === 'undefined' || typeof progressTrackedRef.current[id][step] === 'undefined'));
stepsToTrack.forEach(step => {
// console.log(
// Math.round(step * 100, 10),
// getVideoMetadata({
// currentTime,
// }),
// );
tracking.trackVideo(`progress ${Math.round(step * 100, 10)}%`, getVideoMetadata({
currentTime
}));
});
if (stepsToTrack !== null && stepsToTrack.length > 0) {
progressTrackedRef.current = {
...progressTrackedRef.current,
[id]: {
...progressTrackedRef.current[id],
...stepsToTrack.reduce((stepsMap, step) => ({
...stepsMap,
[step]: true
}), {})
}
};
}
}, [currentTime, progressTrackedRef.current, id]);
}
export { Tracking$1 as Tracking, TrackingContainer, TrackingContext$1 as TrackingContext, Tracking$1 as default, useTracking$1 as useTracking, useVideoTracking, withTracking$1 as withTracking };

7

package.json
{
"name": "@folklore/tracking",
"version": "0.0.20",
"version": "0.0.21",
"description": "Tracking utilities",

@@ -43,3 +43,4 @@ "keywords": [

"@babel/runtime": "^7.4.3",
"prop-types": "^15.7.2"
"prop-types": "^15.7.2",
"uuid": "^10.0.0"
},

@@ -54,3 +55,3 @@ "devDependencies": {

},
"gitHead": "ee61fcb16d9b0001aabfdf9c241723a9e0bff6b5"
"gitHead": "76f400a041038b006a93161398d46ba0c921c12e"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc