@vouchfor/embeds 0.0.0-experiment.4eb5f06 → 0.0.0-experiment.526750e
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/dist/es/components/Embed/controllers/tracking.d.ts +2 -1
- package/dist/es/embeds.js +53 -55
- package/dist/es/embeds.js.map +1 -1
- package/dist/iife/embeds.iife.js +38 -38
- package/dist/iife/embeds.iife.js.map +1 -1
- package/package.json +2 -2
- package/src/components/Embed/controllers/fetcher.ts +2 -2
- package/src/components/Embed/controllers/tracking.ts +37 -50
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vouchfor/embeds",
|
3
|
-
"version": "0.0.0-experiment.
|
3
|
+
"version": "0.0.0-experiment.526750e",
|
4
4
|
"license": "MIT",
|
5
5
|
"author": "Aaron Williams",
|
6
6
|
"main": "dist/es/embeds.js",
|
@@ -36,7 +36,7 @@
|
|
36
36
|
},
|
37
37
|
"dependencies": {
|
38
38
|
"@lit/task": "^1.0.0",
|
39
|
-
"@vouchfor/media-player": "0.0.0-experiment.
|
39
|
+
"@vouchfor/media-player": "0.0.0-experiment.526750e",
|
40
40
|
"uuid": "^9.0.1"
|
41
41
|
},
|
42
42
|
"peerDependencies": {
|
@@ -51,7 +51,7 @@ class FetcherController {
|
|
51
51
|
// so to ensure that the cache stays up to date, whenever we detect a cache hit we trigger another
|
52
52
|
// API call with the `Cache-Control` header which will re-fill the cache
|
53
53
|
const resCacheCheck = res?.headers?.get('X-Cache-Check');
|
54
|
-
if (resCacheCheck
|
54
|
+
if (resCacheCheck !== cacheCheck) {
|
55
55
|
fetch(`${embedApiUrl}/vouches/${vouchId}`, {
|
56
56
|
method: 'GET',
|
57
57
|
headers: [
|
@@ -81,7 +81,7 @@ class FetcherController {
|
|
81
81
|
// so to ensure that the cache stays up to date, whenever we detect a cache hit we trigger another
|
82
82
|
// API call with the `Cache-Control` header which will re-fill the cache
|
83
83
|
const resCacheCheck = res?.headers?.get('X-Cache-Check');
|
84
|
-
if (resCacheCheck
|
84
|
+
if (resCacheCheck !== cacheCheck) {
|
85
85
|
fetch(`${embedApiUrl}/templates/${templateId}`, {
|
86
86
|
method: 'GET',
|
87
87
|
headers: [
|
@@ -1,4 +1,3 @@
|
|
1
|
-
/* eslint-disable max-lines */
|
2
1
|
import { v4 as uuidv4 } from 'uuid';
|
3
2
|
|
4
3
|
import type { Embed } from '..';
|
@@ -14,7 +13,6 @@ type EmbedHost = ReactiveControllerHost & Embed;
|
|
14
13
|
|
15
14
|
type TrackingEvent = 'VOUCH_LOADED' | 'VOUCH_RESPONSE_VIEWED' | 'VIDEO_PLAYED' | 'VIDEO_STREAMED';
|
16
15
|
type TrackingPayload = {
|
17
|
-
vouchId: string;
|
18
16
|
answerId?: string;
|
19
17
|
streamStart?: number;
|
20
18
|
streamEnd?: number;
|
@@ -38,8 +36,9 @@ class TrackingController implements ReactiveController {
|
|
38
36
|
private _hasPlayed = false;
|
39
37
|
private _hasLoaded: BooleanMap = {};
|
40
38
|
private _answersViewed: BooleanMap = {};
|
41
|
-
private
|
39
|
+
private _streamStartTime: TimeMap = {};
|
42
40
|
private _streamLatestTime: TimeMap = {};
|
41
|
+
private _currentlyPlayingVideo: VideoEventDetail | null = null;
|
43
42
|
|
44
43
|
constructor(host: EmbedHost) {
|
45
44
|
this.host = host;
|
@@ -130,14 +129,16 @@ class TrackingController implements ReactiveController {
|
|
130
129
|
};
|
131
130
|
};
|
132
131
|
|
133
|
-
private _sendTrackingEvent = (event: TrackingEvent, payload
|
134
|
-
const
|
135
|
-
const { client, tab, request, visitor } = this._getUids();
|
132
|
+
private _sendTrackingEvent = (event: TrackingEvent, payload?: TrackingPayload) => {
|
133
|
+
const vouchId = this._findVouchId();
|
136
134
|
|
137
|
-
if (this.host.disableTracking) {
|
135
|
+
if (!vouchId || this.host.disableTracking) {
|
138
136
|
return;
|
139
137
|
}
|
140
138
|
|
139
|
+
const { publicApiUrl } = getEnvUrls(this.host.env);
|
140
|
+
const { client, tab, request, visitor } = this._getUids();
|
141
|
+
|
141
142
|
navigator.sendBeacon(
|
142
143
|
`${publicApiUrl}/api/events`,
|
143
144
|
JSON.stringify({
|
@@ -161,24 +162,15 @@ class TrackingController implements ReactiveController {
|
|
161
162
|
|
162
163
|
// Only send loaded event once per session
|
163
164
|
if (!this._hasLoaded[vouchId]) {
|
164
|
-
this._sendTrackingEvent('VOUCH_LOADED'
|
165
|
-
vouchId
|
166
|
-
});
|
165
|
+
this._sendTrackingEvent('VOUCH_LOADED');
|
167
166
|
this._hasLoaded[vouchId] = true;
|
168
167
|
}
|
169
168
|
};
|
170
169
|
|
171
170
|
private _handlePlay = () => {
|
172
|
-
const vouchId = this._findVouchId();
|
173
|
-
|
174
|
-
if (!vouchId) {
|
175
|
-
return;
|
176
|
-
}
|
177
|
-
|
178
171
|
// Only send the video played event once per session
|
179
172
|
if (!this._hasPlayed) {
|
180
173
|
this._sendTrackingEvent('VIDEO_PLAYED', {
|
181
|
-
vouchId,
|
182
174
|
streamStart: this.host.currentTime
|
183
175
|
});
|
184
176
|
this._hasPlayed = true;
|
@@ -186,76 +178,57 @@ class TrackingController implements ReactiveController {
|
|
186
178
|
};
|
187
179
|
|
188
180
|
private _handleVideoPlay = ({ detail: { id, key, node } }: CustomEvent<VideoEventDetail>) => {
|
189
|
-
const vouchId = this._findVouchId();
|
190
|
-
|
191
|
-
if (!vouchId) {
|
192
|
-
return;
|
193
|
-
}
|
194
|
-
|
195
181
|
// Only increment play count once per session
|
196
182
|
if (!this._answersViewed[key]) {
|
197
183
|
this._sendTrackingEvent('VOUCH_RESPONSE_VIEWED', {
|
198
|
-
vouchId,
|
199
184
|
answerId: id
|
200
185
|
});
|
201
186
|
this._answersViewed[key] = true;
|
202
187
|
}
|
203
188
|
|
204
|
-
this.
|
189
|
+
this._streamStartTime[key] = node.currentTime;
|
205
190
|
this._streamLatestTime[key] = node.currentTime;
|
206
191
|
};
|
207
192
|
|
208
193
|
private _handleVideoTimeUpdate = ({ detail: { id, key, node } }: CustomEvent<VideoEventDetail>) => {
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
194
|
+
// We only want to count any time that the video is actually playing
|
195
|
+
if (!this.host.paused) {
|
196
|
+
this._currentlyPlayingVideo = { id, key, node };
|
197
|
+
this._streamLatestTime[key] = node.currentTime;
|
213
198
|
}
|
214
199
|
|
215
200
|
if (
|
216
|
-
node.currentTime &&
|
217
201
|
!node.paused &&
|
218
202
|
!this.host.paused &&
|
219
203
|
// Only fire the video seeked event when this video is the active one
|
220
204
|
id === this.host.scene?.video?.id &&
|
221
205
|
// Throttle the frequency that we send streamed events while playing
|
222
|
-
|
206
|
+
this._streamLatestTime[key] - this._streamStartTime[key] > STREAMED_THROTTLE
|
223
207
|
) {
|
224
208
|
this._sendTrackingEvent('VIDEO_STREAMED', {
|
225
|
-
vouchId,
|
226
209
|
answerId: id,
|
227
|
-
streamStart: this.
|
228
|
-
streamEnd:
|
210
|
+
streamStart: this._streamStartTime[key],
|
211
|
+
streamEnd: this._streamLatestTime[key]
|
229
212
|
});
|
230
|
-
this._streamedTime[key] = node.currentTime;
|
231
|
-
}
|
232
213
|
|
233
|
-
|
234
|
-
this._streamLatestTime[key] = node.currentTime;
|
214
|
+
this._streamStartTime[key] = node.currentTime;
|
235
215
|
}
|
236
216
|
};
|
237
217
|
|
238
218
|
private _handleVideoPause = ({ detail: { id, key } }: CustomEvent<VideoEventDetail>) => {
|
239
|
-
|
240
|
-
|
241
|
-
if (!vouchId) {
|
242
|
-
return;
|
243
|
-
}
|
244
|
-
|
245
|
-
// Don't send a tracking event if the video pauses when seeking backwards
|
246
|
-
if (this._streamLatestTime[key] > this._streamedTime[key] + 0.5) {
|
219
|
+
// Don't send a tracking event when seeking backwards
|
220
|
+
if (this._streamLatestTime[key] > this._streamStartTime[key]) {
|
247
221
|
// Send a video streamed event any time the video pauses then reset the streamed state
|
248
222
|
// We do this to capture the last bit of time that the video was played between the previous
|
249
223
|
// stream event and the video being paused manually or stopping because it ended
|
250
224
|
this._sendTrackingEvent('VIDEO_STREAMED', {
|
251
|
-
vouchId,
|
252
225
|
answerId: id,
|
253
|
-
streamStart: this.
|
226
|
+
streamStart: this._streamStartTime[key],
|
254
227
|
streamEnd: this._streamLatestTime[key]
|
255
228
|
});
|
256
229
|
}
|
257
|
-
|
258
|
-
delete this.
|
230
|
+
this._currentlyPlayingVideo = null;
|
231
|
+
delete this._streamStartTime[key];
|
259
232
|
delete this._streamLatestTime[key];
|
260
233
|
};
|
261
234
|
|
@@ -270,6 +243,20 @@ class TrackingController implements ReactiveController {
|
|
270
243
|
}
|
271
244
|
|
272
245
|
hostDisconnected() {
|
246
|
+
if (this._currentlyPlayingVideo) {
|
247
|
+
const { id, key } = this._currentlyPlayingVideo;
|
248
|
+
if (this._streamLatestTime[key] > this._streamStartTime[key]) {
|
249
|
+
// Send a video streamed event any time the video pauses then reset the streamed state
|
250
|
+
// We do this to capture the last bit of time that the video was played between the previous
|
251
|
+
// stream event and the video being paused manually or stopping because it ended
|
252
|
+
this._sendTrackingEvent('VIDEO_STREAMED', {
|
253
|
+
answerId: id,
|
254
|
+
streamStart: this._streamStartTime[key],
|
255
|
+
streamEnd: this._streamLatestTime[key]
|
256
|
+
});
|
257
|
+
}
|
258
|
+
}
|
259
|
+
|
273
260
|
this.host.removeEventListener('vouch:loaded', this._handleVouchLoaded);
|
274
261
|
this.host.mediaPlayer?.removeEventListener('play', this._handlePlay);
|
275
262
|
this.host.mediaPlayer?.removeEventListener('video:play', this._handleVideoPlay);
|