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