@eyevinn/player-analytics-client-sdk-web 0.3.0 → 0.4.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/Readme.md +218 -47
- package/dist/index.d.ts +2 -0
- package/dist/index.js +508 -85
- package/dist/index.js.map +1 -1
- package/dist/module.js +508 -85
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +26 -7
- package/dist/types.d.ts.map +1 -1
- package/index.ts +7 -0
- package/package.json +5 -1
- package/spec/PlayerAnalytics.spec.ts +338 -0
- package/spec/PlayerAnalyticsConnector.spec.ts +1474 -0
- package/spec/Reporter.spec.ts +825 -0
- package/spec/support/jasmine.json +7 -0
- package/tsconfig.json +1 -1
package/dist/module.js
CHANGED
|
@@ -148,46 +148,81 @@ var $1d47cc84225ea891$var$__generator = undefined && undefined.__generator || fu
|
|
|
148
148
|
return this;
|
|
149
149
|
}), g;
|
|
150
150
|
};
|
|
151
|
+
var $1d47cc84225ea891$var$MAX_QUEUE_SIZE = 100;
|
|
151
152
|
var $1d47cc84225ea891$export$957313a2f485e5ed = function() {
|
|
152
153
|
function $1d47cc84225ea891$export$957313a2f485e5ed(options) {
|
|
153
|
-
|
|
154
|
-
this.
|
|
154
|
+
var _a;
|
|
155
|
+
this.state = "idle";
|
|
156
|
+
this.eventQueue = [];
|
|
157
|
+
this.initPromise = null;
|
|
158
|
+
this.debug = (_a = options.debug) !== null && _a !== void 0 ? _a : false;
|
|
155
159
|
this.shardId = options.shardId;
|
|
156
160
|
this.eventsinkUrl = options.eventsinkUrl;
|
|
157
161
|
this.sessionId = options.sessionId;
|
|
158
162
|
this.heartbeatInterval = options.heartbeatInterval || $76abaee2435acae3$export$31c453b5fe09788d;
|
|
163
|
+
this.onError = options.onError;
|
|
159
164
|
if (this.debug) console.log("[AnalyticsReporter] Initiated AnalyticsReporter", options);
|
|
160
165
|
}
|
|
166
|
+
Object.defineProperty($1d47cc84225ea891$export$957313a2f485e5ed.prototype, "isInitiated", {
|
|
167
|
+
get: function() {
|
|
168
|
+
return this.state === "ready";
|
|
169
|
+
},
|
|
170
|
+
enumerable: false,
|
|
171
|
+
configurable: true
|
|
172
|
+
});
|
|
161
173
|
$1d47cc84225ea891$export$957313a2f485e5ed.prototype.init = function(sessionId) {
|
|
162
174
|
return $1d47cc84225ea891$var$__awaiter(this, void 0, Promise, function() {
|
|
163
|
-
var data,
|
|
175
|
+
var data, result;
|
|
176
|
+
return $1d47cc84225ea891$var$__generator(this, function(_a) {
|
|
177
|
+
if (this.state !== "idle") return [
|
|
178
|
+
2 /*return*/ ,
|
|
179
|
+
this.initPromise
|
|
180
|
+
];
|
|
181
|
+
this.sessionId = sessionId || this.sessionId;
|
|
182
|
+
this.state = "initializing";
|
|
183
|
+
data = {
|
|
184
|
+
event: "init",
|
|
185
|
+
sessionId: this.sessionId,
|
|
186
|
+
shardId: this.shardId,
|
|
187
|
+
timestamp: Date.now(),
|
|
188
|
+
playhead: -1,
|
|
189
|
+
duration: -1
|
|
190
|
+
};
|
|
191
|
+
if (this.debug) {
|
|
192
|
+
console.log("[AnalyticsReporter] Init session:", data);
|
|
193
|
+
this.state = "ready";
|
|
194
|
+
this.flushQueue();
|
|
195
|
+
result = {
|
|
196
|
+
sessionId: this.sessionId,
|
|
197
|
+
heartbeatInterval: this.heartbeatInterval,
|
|
198
|
+
isInitiated: true
|
|
199
|
+
};
|
|
200
|
+
this.initPromise = Promise.resolve(result);
|
|
201
|
+
return [
|
|
202
|
+
2 /*return*/ ,
|
|
203
|
+
this.initPromise
|
|
204
|
+
];
|
|
205
|
+
}
|
|
206
|
+
this.initPromise = this.doInit(data);
|
|
207
|
+
return [
|
|
208
|
+
2 /*return*/ ,
|
|
209
|
+
this.initPromise
|
|
210
|
+
];
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
};
|
|
214
|
+
$1d47cc84225ea891$export$957313a2f485e5ed.prototype.doInit = function(data) {
|
|
215
|
+
return $1d47cc84225ea891$var$__awaiter(this, void 0, Promise, function() {
|
|
216
|
+
var initResponse, initResponseJson, err_1;
|
|
164
217
|
return $1d47cc84225ea891$var$__generator(this, function(_a) {
|
|
165
218
|
switch(_a.label){
|
|
166
219
|
case 0:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
playhead: -1,
|
|
174
|
-
duration: -1
|
|
175
|
-
};
|
|
176
|
-
if (!this.debug) return [
|
|
177
|
-
3 /*break*/ ,
|
|
178
|
-
1
|
|
179
|
-
];
|
|
180
|
-
console.log("[AnalyticsReporter] Init session:", data);
|
|
181
|
-
this.isInitiated = true;
|
|
182
|
-
return [
|
|
183
|
-
2 /*return*/ ,
|
|
184
|
-
{
|
|
185
|
-
sessionId: this.sessionId,
|
|
186
|
-
heartbeatInterval: this.heartbeatInterval,
|
|
187
|
-
isInitiated: this.isInitiated
|
|
188
|
-
}
|
|
189
|
-
];
|
|
190
|
-
case 1:
|
|
220
|
+
_a.trys.push([
|
|
221
|
+
0,
|
|
222
|
+
6,
|
|
223
|
+
,
|
|
224
|
+
7
|
|
225
|
+
]);
|
|
191
226
|
return [
|
|
192
227
|
4 /*yield*/ ,
|
|
193
228
|
fetch("".concat(this.eventsinkUrl), {
|
|
@@ -202,38 +237,150 @@ var $1d47cc84225ea891$export$957313a2f485e5ed = function() {
|
|
|
202
237
|
body: JSON.stringify(data)
|
|
203
238
|
})
|
|
204
239
|
];
|
|
205
|
-
case
|
|
240
|
+
case 1:
|
|
206
241
|
initResponse = _a.sent();
|
|
242
|
+
// Abort if destroy() was called during the await
|
|
243
|
+
if (this.state === "destroyed") throw new Error("[AnalyticsReporter] init aborted: reporter was destroyed");
|
|
207
244
|
if (!initResponse.ok) throw new Error("[AnalyticsReporter] init failed: ".concat(initResponse.statusText));
|
|
208
245
|
return [
|
|
209
246
|
4 /*yield*/ ,
|
|
210
247
|
initResponse.json()
|
|
211
248
|
];
|
|
212
|
-
case
|
|
249
|
+
case 2:
|
|
213
250
|
initResponseJson = _a.sent();
|
|
251
|
+
if (this.state === "destroyed") throw new Error("[AnalyticsReporter] init aborted: reporter was destroyed");
|
|
214
252
|
if (!this.sessionId && !initResponseJson.sessionId) throw new Error("[AnalyticsReporter] init failed: no sessionId");
|
|
215
253
|
if (initResponseJson.sessionId) this.sessionId = initResponseJson.sessionId;
|
|
216
|
-
|
|
254
|
+
_a.label = 3;
|
|
255
|
+
case 3:
|
|
256
|
+
if (!(this.eventQueue.length > 0)) return [
|
|
257
|
+
3 /*break*/ ,
|
|
258
|
+
5
|
|
259
|
+
];
|
|
260
|
+
if (this.state === "destroyed") throw new Error("[AnalyticsReporter] init aborted: reporter was destroyed");
|
|
261
|
+
return [
|
|
262
|
+
4 /*yield*/ ,
|
|
263
|
+
this.flushQueue()
|
|
264
|
+
];
|
|
265
|
+
case 4:
|
|
266
|
+
_a.sent();
|
|
267
|
+
return [
|
|
268
|
+
3 /*break*/ ,
|
|
269
|
+
3
|
|
270
|
+
];
|
|
271
|
+
case 5:
|
|
272
|
+
// Don't transition to ready if destroyed during flush
|
|
273
|
+
if (this.state !== "destroyed") this.state = "ready";
|
|
217
274
|
return [
|
|
218
275
|
2 /*return*/ ,
|
|
219
276
|
{
|
|
220
277
|
heartbeatInterval: this.heartbeatInterval,
|
|
221
278
|
sessionId: this.sessionId,
|
|
222
|
-
isInitiated:
|
|
279
|
+
isInitiated: true
|
|
223
280
|
}
|
|
224
281
|
];
|
|
282
|
+
case 6:
|
|
283
|
+
err_1 = _a.sent();
|
|
284
|
+
// Don't overwrite 'destroyed' state with 'failed'
|
|
285
|
+
if (this.state !== "destroyed") this.state = "failed";
|
|
286
|
+
this.eventQueue = [];
|
|
287
|
+
throw err_1;
|
|
288
|
+
case 7:
|
|
289
|
+
return [
|
|
290
|
+
2 /*return*/
|
|
291
|
+
];
|
|
225
292
|
}
|
|
226
293
|
});
|
|
227
294
|
});
|
|
228
295
|
};
|
|
229
296
|
$1d47cc84225ea891$export$957313a2f485e5ed.prototype.send = function(data) {
|
|
230
|
-
|
|
231
|
-
|
|
297
|
+
switch(this.state){
|
|
298
|
+
case "ready":
|
|
299
|
+
this.dispatch(data);
|
|
300
|
+
break;
|
|
301
|
+
case "initializing":
|
|
302
|
+
if (this.eventQueue.length >= $1d47cc84225ea891$var$MAX_QUEUE_SIZE) {
|
|
303
|
+
console.warn("[AnalyticsReporter] Event queue full, dropping newest event");
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
this.eventQueue.push(data);
|
|
307
|
+
break;
|
|
308
|
+
case "idle":
|
|
309
|
+
console.warn("[AnalyticsReporter] Cannot report before initiation:", data);
|
|
310
|
+
break;
|
|
311
|
+
case "failed":
|
|
312
|
+
console.warn("[AnalyticsReporter] Init failed, cannot send:", data);
|
|
313
|
+
break;
|
|
314
|
+
case "destroyed":
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
$1d47cc84225ea891$export$957313a2f485e5ed.prototype.buildPayload = function(data) {
|
|
319
|
+
return $1d47cc84225ea891$var$__assign($1d47cc84225ea891$var$__assign({
|
|
320
|
+
}, data), {
|
|
232
321
|
sessionId: this.sessionId,
|
|
233
322
|
shardId: this.shardId
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
|
|
323
|
+
});
|
|
324
|
+
};
|
|
325
|
+
/**
|
|
326
|
+
* Deliver an event using a transport that survives page unload (tab close
|
|
327
|
+
* or reload).
|
|
328
|
+
*
|
|
329
|
+
* Uses `navigator.sendBeacon` with a `text/plain` JSON body. A plain-text
|
|
330
|
+
* body with no `X-EPAS-*` headers is a CORS "simple request", so the browser
|
|
331
|
+
* does not issue a preflight — the preflight is what gets dropped while the
|
|
332
|
+
* page is unloading, losing the event (notably the `stopped` event). The
|
|
333
|
+
* eventsink reads the event from the JSON body (`body.event`), not from
|
|
334
|
+
* headers, so the beacon is accepted.
|
|
335
|
+
*
|
|
336
|
+
* Falls back to `fetch(..., { keepalive: true })` when `sendBeacon` is
|
|
337
|
+
* unavailable or refuses the payload. Returns true when the event was handed
|
|
338
|
+
* off to a transport.
|
|
339
|
+
*/ $1d47cc84225ea891$export$957313a2f485e5ed.prototype.sendBeacon = function(data) {
|
|
340
|
+
if (this.state === "destroyed") return false;
|
|
341
|
+
var payload = this.buildPayload(data);
|
|
342
|
+
if (this.debug) {
|
|
343
|
+
console.log("[AnalyticsReporter] Send beacon payload:", payload);
|
|
344
|
+
return true;
|
|
345
|
+
}
|
|
346
|
+
var body = JSON.stringify(payload);
|
|
347
|
+
if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") try {
|
|
348
|
+
var blob = new Blob([
|
|
349
|
+
body
|
|
350
|
+
], {
|
|
351
|
+
type: "text/plain; charset=utf-8"
|
|
352
|
+
});
|
|
353
|
+
if (navigator.sendBeacon(this.eventsinkUrl, blob)) return true;
|
|
354
|
+
} catch (_a) {
|
|
355
|
+
// Fall through to the keepalive fetch fallback below.
|
|
356
|
+
}
|
|
357
|
+
if (typeof fetch === "function") try {
|
|
358
|
+
fetch("".concat(this.eventsinkUrl), {
|
|
359
|
+
method: "POST",
|
|
360
|
+
mode: "cors",
|
|
361
|
+
cache: "no-cache",
|
|
362
|
+
keepalive: true,
|
|
363
|
+
headers: {
|
|
364
|
+
"Content-Type": "text/plain; charset=utf-8"
|
|
365
|
+
},
|
|
366
|
+
body: body
|
|
367
|
+
}).catch(function() {
|
|
368
|
+
// Best-effort during unload — nothing actionable to do on failure.
|
|
369
|
+
});
|
|
370
|
+
return true;
|
|
371
|
+
} catch (_b) {
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
return false;
|
|
375
|
+
};
|
|
376
|
+
$1d47cc84225ea891$export$957313a2f485e5ed.prototype.dispatch = function(data) {
|
|
377
|
+
var _this = this;
|
|
378
|
+
var payload = this.buildPayload(data);
|
|
379
|
+
if (this.debug) {
|
|
380
|
+
console.log("[AnalyticsReporter] Send payload:", payload);
|
|
381
|
+
return Promise.resolve();
|
|
382
|
+
}
|
|
383
|
+
return fetch("".concat(this.eventsinkUrl), {
|
|
237
384
|
method: "POST",
|
|
238
385
|
mode: "cors",
|
|
239
386
|
cache: "no-cache",
|
|
@@ -243,8 +390,73 @@ var $1d47cc84225ea891$export$957313a2f485e5ed = function() {
|
|
|
243
390
|
"X-EPAS-Version": $76abaee2435acae3$export$8a65ed80196068d4
|
|
244
391
|
},
|
|
245
392
|
body: JSON.stringify(payload)
|
|
393
|
+
}).then(function(res) {
|
|
394
|
+
if (res && !res.ok) {
|
|
395
|
+
var error = {
|
|
396
|
+
status: res.status,
|
|
397
|
+
statusText: res.statusText,
|
|
398
|
+
message: "Send failed: ".concat(res.status, " ").concat(res.statusText)
|
|
399
|
+
};
|
|
400
|
+
if (_this.onError) _this.onError(error, data);
|
|
401
|
+
else console.warn("[AnalyticsReporter] ".concat(error.message));
|
|
402
|
+
}
|
|
403
|
+
}).catch(function(err) {
|
|
404
|
+
var error = {
|
|
405
|
+
message: err instanceof Error ? err.message : String(err)
|
|
406
|
+
};
|
|
407
|
+
if (_this.onError) _this.onError(error, data);
|
|
408
|
+
else console.warn("[AnalyticsReporter] Send failed:", error.message);
|
|
246
409
|
});
|
|
247
410
|
};
|
|
411
|
+
$1d47cc84225ea891$export$957313a2f485e5ed.prototype.flushQueue = function() {
|
|
412
|
+
return $1d47cc84225ea891$var$__awaiter(this, void 0, Promise, function() {
|
|
413
|
+
var queued, _i, queued_1, event;
|
|
414
|
+
return $1d47cc84225ea891$var$__generator(this, function(_a) {
|
|
415
|
+
switch(_a.label){
|
|
416
|
+
case 0:
|
|
417
|
+
queued = this.eventQueue;
|
|
418
|
+
this.eventQueue = [];
|
|
419
|
+
_i = 0, queued_1 = queued;
|
|
420
|
+
_a.label = 1;
|
|
421
|
+
case 1:
|
|
422
|
+
if (!(_i < queued_1.length)) return [
|
|
423
|
+
3 /*break*/ ,
|
|
424
|
+
4
|
|
425
|
+
];
|
|
426
|
+
event = queued_1[_i];
|
|
427
|
+
// Abort if destroy() was called mid-flush
|
|
428
|
+
if (this.state === "destroyed") return [
|
|
429
|
+
2 /*return*/
|
|
430
|
+
];
|
|
431
|
+
return [
|
|
432
|
+
4 /*yield*/ ,
|
|
433
|
+
this.dispatch(event)
|
|
434
|
+
];
|
|
435
|
+
case 2:
|
|
436
|
+
_a.sent();
|
|
437
|
+
_a.label = 3;
|
|
438
|
+
case 3:
|
|
439
|
+
_i++;
|
|
440
|
+
return [
|
|
441
|
+
3 /*break*/ ,
|
|
442
|
+
1
|
|
443
|
+
];
|
|
444
|
+
case 4:
|
|
445
|
+
return [
|
|
446
|
+
2 /*return*/
|
|
447
|
+
];
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
};
|
|
452
|
+
/**
|
|
453
|
+
* Tear down the reporter. Aborts any in-flight init, discards queued
|
|
454
|
+
* events without flushing, and prevents future send() calls from
|
|
455
|
+
* dispatching. Called by PlayerAnalytics.destroy().
|
|
456
|
+
*/ $1d47cc84225ea891$export$957313a2f485e5ed.prototype.destroy = function() {
|
|
457
|
+
this.state = "destroyed";
|
|
458
|
+
this.eventQueue = [];
|
|
459
|
+
};
|
|
248
460
|
return $1d47cc84225ea891$export$957313a2f485e5ed;
|
|
249
461
|
}();
|
|
250
462
|
|
|
@@ -372,10 +584,11 @@ var $03bb5e0d0325c534$var$__generator = undefined && undefined.__generator || fu
|
|
|
372
584
|
}), g;
|
|
373
585
|
};
|
|
374
586
|
var $03bb5e0d0325c534$export$f76c463fe9cb9f15 = function() {
|
|
375
|
-
function $03bb5e0d0325c534$export$f76c463fe9cb9f15(eventsinkUrl, debug) {
|
|
587
|
+
function $03bb5e0d0325c534$export$f76c463fe9cb9f15(eventsinkUrl, debug, onError) {
|
|
376
588
|
this.debug = false;
|
|
377
|
-
this.debug = debug;
|
|
589
|
+
this.debug = debug !== null && debug !== void 0 ? debug : false;
|
|
378
590
|
this.eventsinkUrl = eventsinkUrl;
|
|
591
|
+
this.onError = onError;
|
|
379
592
|
}
|
|
380
593
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.initiateAnalyticsReporter = function(_a) {
|
|
381
594
|
var sessionId = _a.sessionId, shardId = _a.shardId, _b = _a.heartbeatInterval, heartbeatInterval = _b === void 0 ? $76abaee2435acae3$export$31c453b5fe09788d : _b;
|
|
@@ -389,7 +602,8 @@ var $03bb5e0d0325c534$export$f76c463fe9cb9f15 = function() {
|
|
|
389
602
|
eventsinkUrl: this.eventsinkUrl,
|
|
390
603
|
debug: this.debug,
|
|
391
604
|
heartbeatInterval: heartbeatInterval,
|
|
392
|
-
shardId: shardId
|
|
605
|
+
shardId: shardId,
|
|
606
|
+
onError: this.onError
|
|
393
607
|
});
|
|
394
608
|
return [
|
|
395
609
|
4 /*yield*/ ,
|
|
@@ -409,52 +623,87 @@ var $03bb5e0d0325c534$export$f76c463fe9cb9f15 = function() {
|
|
|
409
623
|
});
|
|
410
624
|
});
|
|
411
625
|
};
|
|
626
|
+
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.ensureReporter = function() {
|
|
627
|
+
if (!this.analyticsReporter) {
|
|
628
|
+
console.warn("[PlayerAnalytics] Not initialized. Call initiateAnalyticsReporter() first.");
|
|
629
|
+
return false;
|
|
630
|
+
}
|
|
631
|
+
return true;
|
|
632
|
+
};
|
|
412
633
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.init = function(data) {
|
|
634
|
+
if (!this.ensureReporter()) return;
|
|
413
635
|
this.analyticsReporter.send(data);
|
|
414
636
|
};
|
|
415
637
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.metadata = function(data) {
|
|
638
|
+
if (!this.ensureReporter()) return;
|
|
416
639
|
this.analyticsReporter.send(data);
|
|
417
640
|
};
|
|
418
641
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.heartbeat = function(data) {
|
|
642
|
+
if (!this.ensureReporter()) return;
|
|
419
643
|
this.analyticsReporter.send(data);
|
|
420
644
|
};
|
|
421
645
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.loading = function(data) {
|
|
646
|
+
if (!this.ensureReporter()) return;
|
|
422
647
|
this.analyticsReporter.send(data);
|
|
423
648
|
};
|
|
424
649
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.loaded = function(data) {
|
|
650
|
+
if (!this.ensureReporter()) return;
|
|
425
651
|
this.analyticsReporter.send(data);
|
|
426
652
|
};
|
|
427
653
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.playing = function(data) {
|
|
654
|
+
if (!this.ensureReporter()) return;
|
|
428
655
|
this.analyticsReporter.send(data);
|
|
429
656
|
};
|
|
430
657
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.pause = function(data) {
|
|
658
|
+
if (!this.ensureReporter()) return;
|
|
431
659
|
this.analyticsReporter.send(data);
|
|
432
660
|
};
|
|
433
661
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.buffering = function(data) {
|
|
662
|
+
if (!this.ensureReporter()) return;
|
|
434
663
|
this.analyticsReporter.send(data);
|
|
435
664
|
};
|
|
436
665
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.buffered = function(data) {
|
|
666
|
+
if (!this.ensureReporter()) return;
|
|
437
667
|
this.analyticsReporter.send(data);
|
|
438
668
|
};
|
|
439
669
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.seeking = function(data) {
|
|
670
|
+
if (!this.ensureReporter()) return;
|
|
440
671
|
this.analyticsReporter.send(data);
|
|
441
672
|
};
|
|
442
673
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.seeked = function(data) {
|
|
674
|
+
if (!this.ensureReporter()) return;
|
|
443
675
|
this.analyticsReporter.send(data);
|
|
444
676
|
};
|
|
445
677
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.bitrateChanged = function(data) {
|
|
678
|
+
if (!this.ensureReporter()) return;
|
|
446
679
|
this.analyticsReporter.send(data);
|
|
447
680
|
};
|
|
448
681
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.error = function(data) {
|
|
682
|
+
if (!this.ensureReporter()) return;
|
|
449
683
|
this.analyticsReporter.send(data);
|
|
450
684
|
};
|
|
451
685
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.warning = function(data) {
|
|
686
|
+
if (!this.ensureReporter()) return;
|
|
452
687
|
this.analyticsReporter.send(data);
|
|
453
688
|
};
|
|
454
689
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.stopped = function(data) {
|
|
690
|
+
if (!this.ensureReporter()) return;
|
|
455
691
|
this.analyticsReporter.send(data);
|
|
456
692
|
};
|
|
693
|
+
/**
|
|
694
|
+
* Send a stopped event over the reporter's unload-safe beacon transport
|
|
695
|
+
* (navigator.sendBeacon with a fetch keepalive fallback). Used to deliver the
|
|
696
|
+
* stopped event when the page is closed or reloaded mid-playback, where a
|
|
697
|
+
* normal CORS fetch would be dropped during unload. Returns true when the
|
|
698
|
+
* event was handed off to a transport.
|
|
699
|
+
*/ $03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.stoppedViaBeacon = function(data) {
|
|
700
|
+
if (!this.ensureReporter()) return false;
|
|
701
|
+
return this.analyticsReporter.sendBeacon(data);
|
|
702
|
+
};
|
|
457
703
|
$03bb5e0d0325c534$export$f76c463fe9cb9f15.prototype.destroy = function() {
|
|
704
|
+
// Cascade destroy to the reporter so any in-flight init is aborted
|
|
705
|
+
// and queued events are discarded rather than flushed.
|
|
706
|
+
if (this.analyticsReporter) this.analyticsReporter.destroy();
|
|
458
707
|
this.analyticsReporter = null;
|
|
459
708
|
};
|
|
460
709
|
return $03bb5e0d0325c534$export$f76c463fe9cb9f15;
|
|
@@ -599,33 +848,83 @@ var $85819f9bdebfd936$var$__generator = undefined && undefined.__generator || fu
|
|
|
599
848
|
}), g;
|
|
600
849
|
};
|
|
601
850
|
var $85819f9bdebfd936$export$2daf9923c014a26e = function() {
|
|
602
|
-
function $85819f9bdebfd936$export$2daf9923c014a26e(eventsinkUrl, debug) {
|
|
851
|
+
function $85819f9bdebfd936$export$2daf9923c014a26e(eventsinkUrl, debug, onError) {
|
|
852
|
+
var _this = this;
|
|
603
853
|
this.analyticsInitiated = false;
|
|
854
|
+
this.initCalled = false;
|
|
855
|
+
this.initGeneration = 0;
|
|
856
|
+
// Direct DOM fallback for terminal/seek events on an element that was already
|
|
857
|
+
// playing when load() ran (autoplay started during a slow init() handshake).
|
|
858
|
+
// The media-event-filter attaches in its "loading" state and, never having
|
|
859
|
+
// observed the initial playing/canplaythrough transitions, stays stuck there
|
|
860
|
+
// and suppresses ENDED/SEEKING/SEEKED. These listeners drive that path
|
|
861
|
+
// directly. They self-disable the moment the filter proves it is live (emits
|
|
862
|
+
// any event), so a seek is never reported twice across the two sources.
|
|
863
|
+
this.autoplayFallbackActive = false;
|
|
864
|
+
this.pendingHeartbeatStart = false;
|
|
865
|
+
// Tracks whether a stopped event has already been reported for the current
|
|
866
|
+
// session, so the page-unload path does not emit a duplicate after an
|
|
867
|
+
// `ended`, reportStop(), or reportError() has already stopped the session.
|
|
868
|
+
this.stoppedReported = false;
|
|
869
|
+
this.unloadListenersRegistered = false;
|
|
870
|
+
this.handleAutoplayEnded = function() {
|
|
871
|
+
// Mirror the filter's ENDED branch: exactly one stopped(ended), stop
|
|
872
|
+
// heartbeats, and respect the stoppedReported guard so reportStop/
|
|
873
|
+
// reportError/unload can't produce a duplicate.
|
|
874
|
+
if (_this.stoppedReported) return;
|
|
875
|
+
_this.stoppedReported = true;
|
|
876
|
+
_this.stopInterval();
|
|
877
|
+
_this.sendFilteredEvent("stopped", {
|
|
878
|
+
reason: "ended"
|
|
879
|
+
});
|
|
880
|
+
};
|
|
881
|
+
this.handleAutoplaySeeking = function() {
|
|
882
|
+
_this.sendFilteredEvent("seeking");
|
|
883
|
+
};
|
|
884
|
+
this.handleAutoplaySeeked = function() {
|
|
885
|
+
_this.sendFilteredEvent("seeked");
|
|
886
|
+
};
|
|
887
|
+
this.handlePageHide = function() {
|
|
888
|
+
_this.flushStoppedOnUnload();
|
|
889
|
+
};
|
|
604
890
|
this.eventsinkUrl = eventsinkUrl;
|
|
605
|
-
this.playerAnalytics = new $03bb5e0d0325c534$exports.PlayerAnalytics(this.eventsinkUrl, debug);
|
|
891
|
+
this.playerAnalytics = new $03bb5e0d0325c534$exports.PlayerAnalytics(this.eventsinkUrl, debug, onError);
|
|
606
892
|
}
|
|
607
893
|
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.init = function(options) {
|
|
608
894
|
return $85819f9bdebfd936$var$__awaiter(this, void 0, void 0, function() {
|
|
609
|
-
var
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
895
|
+
var currentGeneration, initPromise;
|
|
896
|
+
var _this = this;
|
|
897
|
+
return $85819f9bdebfd936$var$__generator(this, function(_a) {
|
|
898
|
+
this.sessionId = options.sessionId;
|
|
899
|
+
this.initCalled = true;
|
|
900
|
+
this.stoppedReported = false;
|
|
901
|
+
currentGeneration = ++this.initGeneration;
|
|
902
|
+
initPromise = this.playerAnalytics.initiateAnalyticsReporter($85819f9bdebfd936$var$__assign($85819f9bdebfd936$var$__assign({
|
|
903
|
+
}, options), {
|
|
904
|
+
sessionId: this.sessionId
|
|
905
|
+
}));
|
|
906
|
+
initPromise.then(function(result) {
|
|
907
|
+
// Ignore stale init completions (e.g., if destroy() was called during init)
|
|
908
|
+
if (currentGeneration !== _this.initGeneration) return;
|
|
909
|
+
_this.analyticsInitiated = result.isInitiated === true;
|
|
910
|
+
_this.heartbeatInterval = Number(result.heartbeatInterval) || _this.heartbeatInterval;
|
|
911
|
+
if (typeof result.sessionId === "string" && result.sessionId) _this.sessionId = result.sessionId;
|
|
912
|
+
if (_this.pendingHeartbeatStart) {
|
|
913
|
+
_this.pendingHeartbeatStart = false;
|
|
914
|
+
_this.startInterval();
|
|
915
|
+
}
|
|
916
|
+
}).catch(function(err) {
|
|
917
|
+
if (currentGeneration !== _this.initGeneration) return;
|
|
918
|
+
// Reset pendingHeartbeatStart so a retry doesn't fire heartbeats
|
|
919
|
+
// from a stale flag without a new PLAYING event.
|
|
920
|
+
_this.pendingHeartbeatStart = false;
|
|
921
|
+
var message = err instanceof Error ? err.message : String(err);
|
|
922
|
+
console.warn("[PlayerAnalyticsConnector] Init failed:", message);
|
|
923
|
+
});
|
|
924
|
+
return [
|
|
925
|
+
2 /*return*/ ,
|
|
926
|
+
initPromise
|
|
927
|
+
];
|
|
629
928
|
});
|
|
630
929
|
});
|
|
631
930
|
};
|
|
@@ -635,6 +934,30 @@ var $85819f9bdebfd936$export$2daf9923c014a26e = function() {
|
|
|
635
934
|
event: "loading"
|
|
636
935
|
}, this.playbackState()));
|
|
637
936
|
this.initiateVideoEventFilter();
|
|
937
|
+
this.registerUnloadListeners();
|
|
938
|
+
// If the element is already playing by the time load() is called (e.g.
|
|
939
|
+
// autoplay started during a slow init() handshake, before listeners were
|
|
940
|
+
// attached), the media-event-filter won't emit a fresh PLAYING for the
|
|
941
|
+
// DOM "playing" event that already fired. Emit it ourselves and start the
|
|
942
|
+
// heartbeat so the session isn't lost. While init() is still in-flight the
|
|
943
|
+
// event is queued by the Reporter and the heartbeat start is deferred via
|
|
944
|
+
// pendingHeartbeatStart, flushing once the handshake completes.
|
|
945
|
+
if (this.isPlayerAlreadyPlaying()) {
|
|
946
|
+
this.playerAnalytics.playing($85819f9bdebfd936$var$__assign({
|
|
947
|
+
event: "playing"
|
|
948
|
+
}, this.playbackState()));
|
|
949
|
+
this.startInterval();
|
|
950
|
+
// The filter won't emit terminal/seek events for this already-playing
|
|
951
|
+
// element (see isPlayerAlreadyPlaying / initiateVideoEventFilter notes),
|
|
952
|
+
// so drive ended/seeking/seeked from the element's own DOM events.
|
|
953
|
+
this.attachAutoplayTerminalFallback();
|
|
954
|
+
}
|
|
955
|
+
};
|
|
956
|
+
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.isPlayerAlreadyPlaying = function() {
|
|
957
|
+
// HAVE_FUTURE_DATA (readyState 3) mirrors the media-event-filter's own
|
|
958
|
+
// "ready" threshold. Use the numeric literal rather than
|
|
959
|
+
// HTMLMediaElement.HAVE_FUTURE_DATA so this works in non-DOM test envs.
|
|
960
|
+
return !!(this.player && !this.player.paused && !this.player.ended && this.player.readyState >= 3);
|
|
638
961
|
};
|
|
639
962
|
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.initiateVideoEventFilter = function() {
|
|
640
963
|
var _this = this;
|
|
@@ -643,6 +966,11 @@ var $85819f9bdebfd936$export$2daf9923c014a26e = function() {
|
|
|
643
966
|
mediaElement: this.player,
|
|
644
967
|
mp4Mode: false,
|
|
645
968
|
callback: function(event) {
|
|
969
|
+
// The filter emitting anything means it has left its initial "loading"
|
|
970
|
+
// state and is now the authoritative source for terminal/seek events;
|
|
971
|
+
// retire the autoplay DOM fallback so a single seek/ended is not
|
|
972
|
+
// reported twice.
|
|
973
|
+
_this.detachAutoplayTerminalFallback();
|
|
646
974
|
var eventType;
|
|
647
975
|
var extraData = {
|
|
648
976
|
};
|
|
@@ -670,32 +998,65 @@ var $85819f9bdebfd936$export$2daf9923c014a26e = function() {
|
|
|
670
998
|
eventType = "buffered";
|
|
671
999
|
break;
|
|
672
1000
|
case $hCgyA$FilteredMediaEvent.ENDED:
|
|
1001
|
+
// Guard against a duplicate stopped(ended) if the autoplay fallback
|
|
1002
|
+
// (or reportStop/reportError) already ended the session.
|
|
1003
|
+
if (_this.stoppedReported) return;
|
|
673
1004
|
eventType = "stopped";
|
|
674
1005
|
extraData["reason"] = "ended";
|
|
1006
|
+
_this.stoppedReported = true;
|
|
675
1007
|
_this.stopInterval();
|
|
676
1008
|
break;
|
|
677
1009
|
default:
|
|
678
1010
|
break;
|
|
679
1011
|
}
|
|
680
|
-
|
|
681
|
-
if (!_this.analyticsInitiated) {
|
|
682
|
-
console.warn("[PlayerAnalyticsConnector] Analytics not initiated");
|
|
683
|
-
return;
|
|
684
|
-
}
|
|
685
|
-
if (eventType) _this.playerAnalytics[eventType == "paused" ? "pause" : eventType]($85819f9bdebfd936$var$__assign($85819f9bdebfd936$var$__assign({
|
|
686
|
-
event: eventType
|
|
687
|
-
}, _this.playbackState()), Object.keys(extraData).length > 0 && {
|
|
688
|
-
payload: extraData
|
|
689
|
-
}));
|
|
690
|
-
} catch (err) {
|
|
691
|
-
console.error(err);
|
|
692
|
-
}
|
|
1012
|
+
_this.sendFilteredEvent(eventType, extraData);
|
|
693
1013
|
}
|
|
694
1014
|
});
|
|
695
1015
|
};
|
|
1016
|
+
// Shared emit path for events sourced from the media-event-filter and from
|
|
1017
|
+
// the autoplay DOM fallback, so both behave identically (init guard, the
|
|
1018
|
+
// paused→pause method-name mapping, optional payload, error swallowing).
|
|
1019
|
+
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.sendFilteredEvent = function(eventType, extraData) {
|
|
1020
|
+
if (extraData === void 0) extraData = {
|
|
1021
|
+
};
|
|
1022
|
+
try {
|
|
1023
|
+
if (!this.initCalled) {
|
|
1024
|
+
console.warn("[PlayerAnalyticsConnector] Analytics not initiated");
|
|
1025
|
+
return;
|
|
1026
|
+
}
|
|
1027
|
+
if (eventType) this.playerAnalytics[eventType == "paused" ? "pause" : eventType]($85819f9bdebfd936$var$__assign($85819f9bdebfd936$var$__assign({
|
|
1028
|
+
event: eventType
|
|
1029
|
+
}, this.playbackState()), Object.keys(extraData).length > 0 && {
|
|
1030
|
+
payload: extraData
|
|
1031
|
+
}));
|
|
1032
|
+
} catch (err) {
|
|
1033
|
+
console.error(err);
|
|
1034
|
+
}
|
|
1035
|
+
};
|
|
1036
|
+
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.attachAutoplayTerminalFallback = function() {
|
|
1037
|
+
if (this.autoplayFallbackActive) return;
|
|
1038
|
+
if (!this.player || typeof this.player.addEventListener !== "function") return;
|
|
1039
|
+
this.autoplayFallbackActive = true;
|
|
1040
|
+
this.player.addEventListener("ended", this.handleAutoplayEnded);
|
|
1041
|
+
this.player.addEventListener("seeking", this.handleAutoplaySeeking);
|
|
1042
|
+
this.player.addEventListener("seeked", this.handleAutoplaySeeked);
|
|
1043
|
+
};
|
|
1044
|
+
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.detachAutoplayTerminalFallback = function() {
|
|
1045
|
+
if (!this.autoplayFallbackActive) return;
|
|
1046
|
+
this.autoplayFallbackActive = false;
|
|
1047
|
+
if (this.player && typeof this.player.removeEventListener === "function") {
|
|
1048
|
+
this.player.removeEventListener("ended", this.handleAutoplayEnded);
|
|
1049
|
+
this.player.removeEventListener("seeking", this.handleAutoplaySeeking);
|
|
1050
|
+
this.player.removeEventListener("seeked", this.handleAutoplaySeeked);
|
|
1051
|
+
}
|
|
1052
|
+
};
|
|
696
1053
|
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.startInterval = function() {
|
|
697
1054
|
var _this = this;
|
|
698
1055
|
if (this.heartbeatIntervalTimer) return;
|
|
1056
|
+
if (!this.heartbeatInterval) {
|
|
1057
|
+
this.pendingHeartbeatStart = true;
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
699
1060
|
this.heartbeatIntervalTimer = setInterval(function() {
|
|
700
1061
|
_this.playerAnalytics.heartbeat($85819f9bdebfd936$var$__assign({
|
|
701
1062
|
event: "heartbeat"
|
|
@@ -704,9 +1065,11 @@ var $85819f9bdebfd936$export$2daf9923c014a26e = function() {
|
|
|
704
1065
|
};
|
|
705
1066
|
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.stopInterval = function() {
|
|
706
1067
|
clearInterval(this.heartbeatIntervalTimer);
|
|
1068
|
+
this.heartbeatIntervalTimer = null;
|
|
1069
|
+
this.pendingHeartbeatStart = false;
|
|
707
1070
|
};
|
|
708
1071
|
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.reportBitrateChange = function(payload) {
|
|
709
|
-
if (!this.
|
|
1072
|
+
if (!this.initCalled) {
|
|
710
1073
|
console.warn("[PlayerAnalyticsConnector] Analytics not initiated");
|
|
711
1074
|
return;
|
|
712
1075
|
}
|
|
@@ -717,21 +1080,32 @@ var $85819f9bdebfd936$export$2daf9923c014a26e = function() {
|
|
|
717
1080
|
}));
|
|
718
1081
|
};
|
|
719
1082
|
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.reportStop = function() {
|
|
720
|
-
if (!this.
|
|
1083
|
+
if (!this.initCalled) {
|
|
721
1084
|
console.warn("[PlayerAnalyticsConnector] Analytics not initiated");
|
|
722
1085
|
return;
|
|
723
1086
|
}
|
|
724
|
-
this
|
|
1087
|
+
// Already stopped this session (an `ended`, reportError(), or a prior
|
|
1088
|
+
// unload beacon) — don't emit a duplicate stopped.
|
|
1089
|
+
if (this.stoppedReported) return;
|
|
1090
|
+
this.stoppedReported = true;
|
|
1091
|
+
this.stopInterval();
|
|
1092
|
+
// Deliver over the unload-safe beacon transport (sendBeacon / keepalive
|
|
1093
|
+
// fetch), not the normal CORS fetch. Integrators call reportStop() from
|
|
1094
|
+
// pagehide/unload handlers, where the browser drops the preflighted CORS
|
|
1095
|
+
// fetch and the event is lost. Routing through the same beacon the SDK's
|
|
1096
|
+
// own unload path uses means setting `stoppedReported` here lets
|
|
1097
|
+
// flushStoppedOnUnload() short-circuit without losing the event, so
|
|
1098
|
+
// exactly one stopped is delivered.
|
|
1099
|
+
this.playerAnalytics.stoppedViaBeacon($85819f9bdebfd936$var$__assign($85819f9bdebfd936$var$__assign({
|
|
725
1100
|
event: "stopped"
|
|
726
1101
|
}, this.playbackState()), {
|
|
727
1102
|
payload: {
|
|
728
1103
|
reason: "aborted"
|
|
729
1104
|
}
|
|
730
1105
|
}));
|
|
731
|
-
this.stopInterval();
|
|
732
1106
|
};
|
|
733
1107
|
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.reportError = function(error) {
|
|
734
|
-
if (!this.
|
|
1108
|
+
if (!this.initCalled) {
|
|
735
1109
|
console.warn("[PlayerAnalyticsConnector] Analytics not initiated");
|
|
736
1110
|
return;
|
|
737
1111
|
}
|
|
@@ -747,10 +1121,11 @@ var $85819f9bdebfd936$export$2daf9923c014a26e = function() {
|
|
|
747
1121
|
reason: "error"
|
|
748
1122
|
}
|
|
749
1123
|
}));
|
|
1124
|
+
this.stoppedReported = true;
|
|
750
1125
|
this.stopInterval();
|
|
751
1126
|
};
|
|
752
1127
|
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.reportMetadata = function(payload) {
|
|
753
|
-
if (!this.
|
|
1128
|
+
if (!this.initCalled) {
|
|
754
1129
|
console.warn("[PlayerAnalyticsConnector] Analytics not initiated");
|
|
755
1130
|
return;
|
|
756
1131
|
}
|
|
@@ -761,7 +1136,7 @@ var $85819f9bdebfd936$export$2daf9923c014a26e = function() {
|
|
|
761
1136
|
}));
|
|
762
1137
|
};
|
|
763
1138
|
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.reportWarning = function(payload) {
|
|
764
|
-
if (!this.
|
|
1139
|
+
if (!this.initCalled) {
|
|
765
1140
|
console.warn("[PlayerAnalyticsConnector] Analytics not initiated");
|
|
766
1141
|
return;
|
|
767
1142
|
}
|
|
@@ -774,7 +1149,7 @@ var $85819f9bdebfd936$export$2daf9923c014a26e = function() {
|
|
|
774
1149
|
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.playbackState = function() {
|
|
775
1150
|
var _a, _b, _c, _d, _e;
|
|
776
1151
|
var duration = ((_a = this.player) === null || _a === void 0 ? void 0 : _a.duration) && ((_b = this.player) === null || _b === void 0 ? void 0 : _b.duration) !== Infinity && ((_c = this.player) === null || _c === void 0 ? void 0 : _c.duration) > 0 ? this.player.duration : -1;
|
|
777
|
-
var playhead = ((_d = this.player) === null || _d === void 0 ? void 0 : _d.currentTime) &&
|
|
1152
|
+
var playhead = ((_d = this.player) === null || _d === void 0 ? void 0 : _d.currentTime) != null && this.player.currentTime >= 0 ? (_e = this.player) === null || _e === void 0 ? void 0 : _e.currentTime : -1;
|
|
778
1153
|
return {
|
|
779
1154
|
sessionId: this.sessionId,
|
|
780
1155
|
timestamp: Date.now(),
|
|
@@ -782,25 +1157,73 @@ var $85819f9bdebfd936$export$2daf9923c014a26e = function() {
|
|
|
782
1157
|
duration: duration
|
|
783
1158
|
};
|
|
784
1159
|
};
|
|
1160
|
+
/**
|
|
1161
|
+
* Deliver a stopped event when the page is being unloaded (tab closed or
|
|
1162
|
+
* reloaded) mid-session. Driven by `pagehide`, which fires on genuine
|
|
1163
|
+
* discard (close/reload/navigate-away) but NOT on an ordinary tab switch —
|
|
1164
|
+
* the browser drops the normal CORS fetch (it needs a preflight) during
|
|
1165
|
+
* unload, losing the event, so the stopped event goes out over the
|
|
1166
|
+
* reporter's beacon transport instead. It is sent only once per session (a
|
|
1167
|
+
* later `ended`, reportStop(), or reportError() will already have reported
|
|
1168
|
+
* stopped). `visibilitychange→hidden` is deliberately NOT used here: a tab
|
|
1169
|
+
* switch / backgrounding is not an unload and must not end a still-playing
|
|
1170
|
+
* session (see #44).
|
|
1171
|
+
*/ $85819f9bdebfd936$export$2daf9923c014a26e.prototype.flushStoppedOnUnload = function() {
|
|
1172
|
+
if (!this.initCalled || this.stoppedReported || !this.player) return;
|
|
1173
|
+
this.stoppedReported = true;
|
|
1174
|
+
this.stopInterval();
|
|
1175
|
+
this.playerAnalytics.stoppedViaBeacon($85819f9bdebfd936$var$__assign($85819f9bdebfd936$var$__assign({
|
|
1176
|
+
event: "stopped"
|
|
1177
|
+
}, this.playbackState()), {
|
|
1178
|
+
payload: {
|
|
1179
|
+
reason: "aborted"
|
|
1180
|
+
}
|
|
1181
|
+
}));
|
|
1182
|
+
};
|
|
1183
|
+
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.registerUnloadListeners = function() {
|
|
1184
|
+
if (this.unloadListenersRegistered) return;
|
|
1185
|
+
if (typeof window !== "undefined" && typeof window.addEventListener === "function") window.addEventListener("pagehide", this.handlePageHide);
|
|
1186
|
+
this.unloadListenersRegistered = true;
|
|
1187
|
+
};
|
|
1188
|
+
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.removeUnloadListeners = function() {
|
|
1189
|
+
if (!this.unloadListenersRegistered) return;
|
|
1190
|
+
if (typeof window !== "undefined" && typeof window.removeEventListener === "function") window.removeEventListener("pagehide", this.handlePageHide);
|
|
1191
|
+
this.unloadListenersRegistered = false;
|
|
1192
|
+
};
|
|
785
1193
|
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.deinit = function() {
|
|
786
|
-
if (!this.
|
|
1194
|
+
if (!this.initCalled) {
|
|
787
1195
|
console.warn("[PlayerAnalyticsConnector] Analytics not initiated");
|
|
788
1196
|
return;
|
|
789
1197
|
}
|
|
1198
|
+
this.initGeneration++; // Invalidate any pending init callbacks
|
|
1199
|
+
// Abort any in-flight init so queued events don't flush after teardown.
|
|
1200
|
+
// The next init() call creates a fresh Reporter, so destroying the
|
|
1201
|
+
// current one is safe even though deinit is meant to be reusable.
|
|
1202
|
+
this.playerAnalytics.destroy();
|
|
790
1203
|
this.stopInterval();
|
|
1204
|
+
this.removeUnloadListeners();
|
|
1205
|
+
this.detachAutoplayTerminalFallback();
|
|
791
1206
|
this.heartbeatInterval = null;
|
|
792
1207
|
this.videoEventFilter && this.videoEventFilter.teardown();
|
|
793
1208
|
this.videoEventFilter = null;
|
|
1209
|
+
this.analyticsInitiated = false;
|
|
1210
|
+
this.initCalled = false;
|
|
794
1211
|
};
|
|
795
1212
|
$85819f9bdebfd936$export$2daf9923c014a26e.prototype.destroy = function() {
|
|
796
|
-
if (!this.
|
|
1213
|
+
if (!this.initCalled) {
|
|
797
1214
|
console.warn("[PlayerAnalyticsConnector] Analytics not initiated");
|
|
798
1215
|
return;
|
|
799
1216
|
}
|
|
1217
|
+
this.initGeneration++; // Invalidate any pending init callbacks
|
|
1218
|
+
this.stopInterval();
|
|
800
1219
|
this.playerAnalytics.destroy();
|
|
1220
|
+
this.removeUnloadListeners();
|
|
1221
|
+
this.detachAutoplayTerminalFallback();
|
|
801
1222
|
this.heartbeatInterval = null;
|
|
802
1223
|
this.videoEventFilter && this.videoEventFilter.teardown();
|
|
803
|
-
this.
|
|
1224
|
+
this.videoEventFilter = null;
|
|
1225
|
+
this.analyticsInitiated = false;
|
|
1226
|
+
this.initCalled = false;
|
|
804
1227
|
};
|
|
805
1228
|
return $85819f9bdebfd936$export$2daf9923c014a26e;
|
|
806
1229
|
}();
|