@player-ui/metrics-plugin 0.0.1-next.1
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/index.cjs.js +374 -0
- package/dist/index.d.ts +146 -0
- package/dist/index.esm.js +365 -0
- package/package.json +19 -0
- package/src/index.ts +2 -0
- package/src/metrics.ts +586 -0
- package/src/symbols.ts +4 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tapable = require('tapable');
|
|
6
|
+
var beaconPlugin = require('@player-ui/beacon-plugin');
|
|
7
|
+
|
|
8
|
+
const MetricsCorePluginSymbol = Symbol.for("MetricsCorePlugin");
|
|
9
|
+
const MetricsViewBeaconPluginContextSymbol = Symbol.for("MetricsViewBeaconPluginContext");
|
|
10
|
+
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __defProps = Object.defineProperties;
|
|
13
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
14
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
17
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
18
|
+
var __spreadValues = (a, b) => {
|
|
19
|
+
for (var prop in b || (b = {}))
|
|
20
|
+
if (__hasOwnProp.call(b, prop))
|
|
21
|
+
__defNormalProp(a, prop, b[prop]);
|
|
22
|
+
if (__getOwnPropSymbols)
|
|
23
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
24
|
+
if (__propIsEnum.call(b, prop))
|
|
25
|
+
__defNormalProp(a, prop, b[prop]);
|
|
26
|
+
}
|
|
27
|
+
return a;
|
|
28
|
+
};
|
|
29
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
30
|
+
var __async = (__this, __arguments, generator) => {
|
|
31
|
+
return new Promise((resolve, reject) => {
|
|
32
|
+
var fulfilled = (value) => {
|
|
33
|
+
try {
|
|
34
|
+
step(generator.next(value));
|
|
35
|
+
} catch (e) {
|
|
36
|
+
reject(e);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
var rejected = (value) => {
|
|
40
|
+
try {
|
|
41
|
+
step(generator.throw(value));
|
|
42
|
+
} catch (e) {
|
|
43
|
+
reject(e);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
47
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
const defaultGetTime = typeof performance === "undefined" ? () => Date.now() : () => performance.now();
|
|
51
|
+
const callbacks = [
|
|
52
|
+
"onFlowBegin",
|
|
53
|
+
"onFlowEnd",
|
|
54
|
+
"onInteractive",
|
|
55
|
+
"onNodeStart",
|
|
56
|
+
"onNodeEnd",
|
|
57
|
+
"onRenderStart",
|
|
58
|
+
"onRenderEnd",
|
|
59
|
+
"onUpdateStart",
|
|
60
|
+
"onUpdateEnd",
|
|
61
|
+
"onUpdate"
|
|
62
|
+
];
|
|
63
|
+
const _MetricsViewBeaconPlugin = class {
|
|
64
|
+
constructor(metricsPlugin) {
|
|
65
|
+
this.symbol = _MetricsViewBeaconPlugin.Symbol;
|
|
66
|
+
this.metricsPlugin = metricsPlugin;
|
|
67
|
+
this.metricsPlugin.hooks.onRenderEnd.tap("MetricsViewBeaconPlugin", (timing) => {
|
|
68
|
+
if (timing.completed && this.resolvePendingRenderTime) {
|
|
69
|
+
this.resolvePendingRenderTime(timing.duration);
|
|
70
|
+
this.resolvePendingRenderTime = void 0;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
apply(beaconPlugin) {
|
|
75
|
+
beaconPlugin.hooks.buildBeacon.intercept({
|
|
76
|
+
context: true,
|
|
77
|
+
call: (context, beacon) => {
|
|
78
|
+
if (context && beacon.action === "viewed") {
|
|
79
|
+
context[this.symbol] = this.buildContext();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
buildContext() {
|
|
85
|
+
return __async(this, null, function* () {
|
|
86
|
+
return {
|
|
87
|
+
renderTime: yield this.getRenderTime(),
|
|
88
|
+
requestTime: this.getRequestTime()
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
getRenderTime() {
|
|
93
|
+
return __async(this, null, function* () {
|
|
94
|
+
const { flow } = this.metricsPlugin.getMetrics();
|
|
95
|
+
if (flow) {
|
|
96
|
+
const lastItem = flow.timeline[flow.timeline.length - 1];
|
|
97
|
+
if ("render" in lastItem && lastItem.render.completed) {
|
|
98
|
+
return lastItem.render.duration;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return new Promise((resolve) => {
|
|
102
|
+
this.resolvePendingRenderTime = resolve;
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
getRequestTime() {
|
|
107
|
+
const { flow } = this.metricsPlugin.getMetrics();
|
|
108
|
+
return flow == null ? void 0 : flow.requestTime;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
let MetricsViewBeaconPlugin = _MetricsViewBeaconPlugin;
|
|
112
|
+
MetricsViewBeaconPlugin.Symbol = MetricsViewBeaconPluginContextSymbol;
|
|
113
|
+
class RequestTimeWebPlugin {
|
|
114
|
+
constructor(getRequestTime) {
|
|
115
|
+
this.name = "RequestTimeWebPlugin";
|
|
116
|
+
this.getRequestTime = getRequestTime;
|
|
117
|
+
}
|
|
118
|
+
apply(metricsCorePlugin) {
|
|
119
|
+
metricsCorePlugin.hooks.resolveRequestTime.tap(this.name, () => {
|
|
120
|
+
return this.getRequestTime();
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
class MetricsCorePlugin {
|
|
125
|
+
constructor(options) {
|
|
126
|
+
this.name = "metrics";
|
|
127
|
+
this.symbol = MetricsCorePluginSymbol;
|
|
128
|
+
this.hooks = {
|
|
129
|
+
resolveRequestTime: new tapable.SyncBailHook(["requestTime"]),
|
|
130
|
+
onFlowBegin: new tapable.SyncHook(["update"]),
|
|
131
|
+
onFlowEnd: new tapable.SyncHook(["update"]),
|
|
132
|
+
onInteractive: new tapable.SyncHook([
|
|
133
|
+
"timing",
|
|
134
|
+
"update"
|
|
135
|
+
]),
|
|
136
|
+
onNodeStart: new tapable.SyncHook([
|
|
137
|
+
"nodeMetrics",
|
|
138
|
+
"update"
|
|
139
|
+
]),
|
|
140
|
+
onNodeEnd: new tapable.SyncHook([
|
|
141
|
+
"nodeMetrics",
|
|
142
|
+
"update"
|
|
143
|
+
]),
|
|
144
|
+
onRenderStart: new tapable.SyncHook([
|
|
145
|
+
"timing",
|
|
146
|
+
"nodeMetrics",
|
|
147
|
+
"update"
|
|
148
|
+
]),
|
|
149
|
+
onRenderEnd: new tapable.SyncHook([
|
|
150
|
+
"timing",
|
|
151
|
+
"nodeMetrics",
|
|
152
|
+
"update"
|
|
153
|
+
]),
|
|
154
|
+
onUpdateStart: new tapable.SyncHook([
|
|
155
|
+
"timing",
|
|
156
|
+
"nodeMetrics",
|
|
157
|
+
"update"
|
|
158
|
+
]),
|
|
159
|
+
onUpdateEnd: new tapable.SyncHook([
|
|
160
|
+
"timing",
|
|
161
|
+
"nodeMetrics",
|
|
162
|
+
"update"
|
|
163
|
+
]),
|
|
164
|
+
onUpdate: new tapable.SyncHook(["update"])
|
|
165
|
+
};
|
|
166
|
+
this.metrics = {};
|
|
167
|
+
var _a, _b, _c;
|
|
168
|
+
this.trackRender = (_a = options == null ? void 0 : options.trackRenderTime) != null ? _a : false;
|
|
169
|
+
this.trackUpdate = (_b = options == null ? void 0 : options.trackUpdateTime) != null ? _b : false;
|
|
170
|
+
this.getTime = (_c = options == null ? void 0 : options.getTime) != null ? _c : defaultGetTime;
|
|
171
|
+
const callOnUpdate = () => {
|
|
172
|
+
this.hooks.onUpdate.call(this.metrics);
|
|
173
|
+
};
|
|
174
|
+
this.hooks.onFlowBegin.tap(this.name, callOnUpdate);
|
|
175
|
+
this.hooks.onFlowEnd.tap(this.name, callOnUpdate);
|
|
176
|
+
this.hooks.onInteractive.tap(this.name, callOnUpdate);
|
|
177
|
+
this.hooks.onNodeStart.tap(this.name, callOnUpdate);
|
|
178
|
+
this.hooks.onNodeEnd.tap(this.name, callOnUpdate);
|
|
179
|
+
this.hooks.onRenderStart.tap(this.name, callOnUpdate);
|
|
180
|
+
this.hooks.onRenderEnd.tap(this.name, callOnUpdate);
|
|
181
|
+
this.hooks.onUpdateStart.tap(this.name, callOnUpdate);
|
|
182
|
+
this.hooks.onUpdateEnd.tap(this.name, callOnUpdate);
|
|
183
|
+
callbacks.forEach((hookName) => {
|
|
184
|
+
if ((options == null ? void 0 : options[hookName]) !== void 0) {
|
|
185
|
+
this.hooks[hookName].tap("options", options == null ? void 0 : options[hookName]);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
getMetrics() {
|
|
190
|
+
return this.metrics;
|
|
191
|
+
}
|
|
192
|
+
renderStart() {
|
|
193
|
+
var _a;
|
|
194
|
+
const timeline = (_a = this.metrics.flow) == null ? void 0 : _a.timeline;
|
|
195
|
+
if (!timeline || timeline.length === 0) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const lastItem = timeline[timeline.length - 1];
|
|
199
|
+
if ("updates" in lastItem) {
|
|
200
|
+
if (lastItem.updates.length > 0) {
|
|
201
|
+
const lastUpdate = lastItem.updates[lastItem.updates.length - 1];
|
|
202
|
+
if (lastUpdate.completed === false) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (!lastItem.render.completed) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const update = {
|
|
210
|
+
completed: false,
|
|
211
|
+
startTime: defaultGetTime()
|
|
212
|
+
};
|
|
213
|
+
lastItem.updates.push(update);
|
|
214
|
+
this.hooks.onUpdateStart.call(update, lastItem, this.metrics);
|
|
215
|
+
} else {
|
|
216
|
+
const renderInfo = __spreadProps(__spreadValues({}, lastItem), {
|
|
217
|
+
render: {
|
|
218
|
+
completed: false,
|
|
219
|
+
startTime: defaultGetTime()
|
|
220
|
+
},
|
|
221
|
+
updates: []
|
|
222
|
+
});
|
|
223
|
+
timeline[timeline.length - 1] = renderInfo;
|
|
224
|
+
this.hooks.onRenderStart.call(renderInfo.render, renderInfo, this.metrics);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
renderEnd() {
|
|
228
|
+
if (!this.trackRender) {
|
|
229
|
+
throw new Error("Must start the metrics-plugin with render tracking enabled");
|
|
230
|
+
}
|
|
231
|
+
const { flow } = this.metrics;
|
|
232
|
+
if (!flow) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const { timeline, interactive } = flow;
|
|
236
|
+
if (!timeline || !interactive || timeline.length === 0) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const lastItem = timeline[timeline.length - 1];
|
|
240
|
+
if (!("render" in lastItem)) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const endTime = defaultGetTime();
|
|
244
|
+
if (lastItem.render.completed) {
|
|
245
|
+
if (lastItem.updates.length === 0) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const lastUpdate = lastItem.updates[lastItem.updates.length - 1];
|
|
249
|
+
if (lastUpdate.completed === true) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const update = __spreadProps(__spreadValues({}, lastUpdate), {
|
|
253
|
+
completed: true,
|
|
254
|
+
endTime,
|
|
255
|
+
duration: endTime - lastUpdate.startTime
|
|
256
|
+
});
|
|
257
|
+
lastItem.updates[lastItem.updates.length - 1] = update;
|
|
258
|
+
this.hooks.onUpdateEnd.call(update, lastItem, this.metrics);
|
|
259
|
+
} else {
|
|
260
|
+
lastItem.render = __spreadProps(__spreadValues({}, lastItem.render), {
|
|
261
|
+
completed: true,
|
|
262
|
+
endTime,
|
|
263
|
+
duration: endTime - lastItem.startTime
|
|
264
|
+
});
|
|
265
|
+
this.hooks.onRenderEnd.call(lastItem.render, lastItem, this.metrics);
|
|
266
|
+
if (!interactive.completed) {
|
|
267
|
+
flow.interactive = __spreadProps(__spreadValues({}, interactive), {
|
|
268
|
+
completed: true,
|
|
269
|
+
duration: endTime - interactive.startTime,
|
|
270
|
+
endTime
|
|
271
|
+
});
|
|
272
|
+
this.hooks.onInteractive.call(flow.interactive, this.metrics);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
apply(player) {
|
|
277
|
+
player.hooks.onStart.tap(this.name, (flow) => {
|
|
278
|
+
const requestTime = this.hooks.resolveRequestTime.call();
|
|
279
|
+
const startTime = defaultGetTime();
|
|
280
|
+
this.metrics = {
|
|
281
|
+
flow: {
|
|
282
|
+
id: flow.id,
|
|
283
|
+
requestTime,
|
|
284
|
+
timeline: [],
|
|
285
|
+
startTime,
|
|
286
|
+
completed: false,
|
|
287
|
+
interactive: {
|
|
288
|
+
completed: false,
|
|
289
|
+
startTime
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
this.hooks.onFlowBegin.call(this.metrics);
|
|
294
|
+
});
|
|
295
|
+
player.hooks.state.tap(this.name, (state) => {
|
|
296
|
+
if (state.status === "completed" || state.status === "error") {
|
|
297
|
+
const endTime = defaultGetTime();
|
|
298
|
+
const { flow } = this.metrics;
|
|
299
|
+
if (flow === void 0 || (flow == null ? void 0 : flow.completed) === true) {
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
this.metrics = {
|
|
303
|
+
flow: __spreadProps(__spreadValues({}, flow), {
|
|
304
|
+
completed: true,
|
|
305
|
+
endTime,
|
|
306
|
+
duration: endTime - flow.startTime
|
|
307
|
+
})
|
|
308
|
+
};
|
|
309
|
+
const lastUpdate = flow.timeline[flow.timeline.length - 1];
|
|
310
|
+
if (lastUpdate && !lastUpdate.completed) {
|
|
311
|
+
this.metrics.flow.timeline[flow.timeline.length - 1] = __spreadProps(__spreadValues({}, lastUpdate), {
|
|
312
|
+
completed: true,
|
|
313
|
+
endTime,
|
|
314
|
+
duration: endTime - lastUpdate.startTime
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
this.hooks.onFlowEnd.call(this.metrics);
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
player.hooks.flowController.tap(this.name, (fc) => {
|
|
321
|
+
fc.hooks.flow.tap(this.name, (f) => {
|
|
322
|
+
f.hooks.transition.tap(this.name, (from, to) => {
|
|
323
|
+
const time = defaultGetTime();
|
|
324
|
+
const { flow } = this.metrics;
|
|
325
|
+
if (!flow) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
const { timeline } = flow;
|
|
329
|
+
if (timeline.length > 0) {
|
|
330
|
+
const prev = timeline[timeline.length - 1];
|
|
331
|
+
if (prev.completed) {
|
|
332
|
+
throw new Error("Completing a state that's already done.");
|
|
333
|
+
}
|
|
334
|
+
timeline[timeline.length - 1] = __spreadProps(__spreadValues({}, prev), {
|
|
335
|
+
completed: true,
|
|
336
|
+
endTime: time,
|
|
337
|
+
duration: time - prev.startTime
|
|
338
|
+
});
|
|
339
|
+
this.hooks.onNodeEnd.call(timeline[timeline.length - 1]);
|
|
340
|
+
}
|
|
341
|
+
const nodeMetrics = {
|
|
342
|
+
completed: false,
|
|
343
|
+
startTime: time,
|
|
344
|
+
stateName: to.name,
|
|
345
|
+
stateType: to.value.state_type
|
|
346
|
+
};
|
|
347
|
+
timeline.push(nodeMetrics);
|
|
348
|
+
this.hooks.onNodeStart.call(nodeMetrics);
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
if (this.trackRender) {
|
|
353
|
+
player.hooks.view.tap(this.name, (v) => {
|
|
354
|
+
if (this.trackUpdate) {
|
|
355
|
+
v.hooks.onUpdate.tap(this.name, () => {
|
|
356
|
+
this.renderStart();
|
|
357
|
+
});
|
|
358
|
+
} else {
|
|
359
|
+
this.renderStart();
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
player.applyTo(beaconPlugin.BeaconPlugin.Symbol, (beaconPlugin) => new MetricsViewBeaconPlugin(this).apply(beaconPlugin));
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
MetricsCorePlugin.Symbol = MetricsCorePluginSymbol;
|
|
367
|
+
|
|
368
|
+
exports.MetricsCorePlugin = MetricsCorePlugin;
|
|
369
|
+
exports.MetricsCorePluginSymbol = MetricsCorePluginSymbol;
|
|
370
|
+
exports.MetricsViewBeaconPlugin = MetricsViewBeaconPlugin;
|
|
371
|
+
exports.MetricsViewBeaconPluginContextSymbol = MetricsViewBeaconPluginContextSymbol;
|
|
372
|
+
exports.RequestTimeWebPlugin = RequestTimeWebPlugin;
|
|
373
|
+
exports.defaultGetTime = defaultGetTime;
|
|
374
|
+
//# sourceMappingURL=index.cjs.js.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { PlayerPlugin, Player } from '@player-ui/player';
|
|
2
|
+
import { SyncBailHook, SyncHook } from 'tapable';
|
|
3
|
+
import { BeaconPluginPlugin, BeaconPlugin } from '@player-ui/beacon-plugin';
|
|
4
|
+
|
|
5
|
+
declare const defaultGetTime: () => number;
|
|
6
|
+
declare type Timing = {
|
|
7
|
+
/** Time this duration started (ms) */
|
|
8
|
+
startTime: number;
|
|
9
|
+
} & ({
|
|
10
|
+
/** Flag set if this is currently in progress */
|
|
11
|
+
completed: false;
|
|
12
|
+
} | {
|
|
13
|
+
/** The stopwatch has stopped */
|
|
14
|
+
completed: true;
|
|
15
|
+
/** The time in (ms) that the process ended */
|
|
16
|
+
endTime: number;
|
|
17
|
+
/** The elapsed time of this event (ms) */
|
|
18
|
+
duration: number;
|
|
19
|
+
});
|
|
20
|
+
declare type NodeMetrics = Timing & {
|
|
21
|
+
/** The type of the flow-state */
|
|
22
|
+
stateType: string;
|
|
23
|
+
/** The name of the flow-state */
|
|
24
|
+
stateName: string;
|
|
25
|
+
};
|
|
26
|
+
declare type NodeRenderMetrics = NodeMetrics & {
|
|
27
|
+
/** Timing representing the initial render */
|
|
28
|
+
render: Timing;
|
|
29
|
+
/** An array of timings representing updates to the view */
|
|
30
|
+
updates: Array<Timing>;
|
|
31
|
+
};
|
|
32
|
+
interface PlayerFlowMetrics {
|
|
33
|
+
/** All metrics about a running flow */
|
|
34
|
+
flow?: {
|
|
35
|
+
/** The id of the flow these metrics are for */
|
|
36
|
+
id: string;
|
|
37
|
+
/** request time */
|
|
38
|
+
requestTime?: number;
|
|
39
|
+
/** A timeline of events for each node-state */
|
|
40
|
+
timeline: Array<NodeMetrics | NodeRenderMetrics>;
|
|
41
|
+
/** A timing measuring until the first interactive render */
|
|
42
|
+
interactive: Timing;
|
|
43
|
+
} & Timing;
|
|
44
|
+
}
|
|
45
|
+
/** Context structure for 'viewed' beacons rendering metrics */
|
|
46
|
+
interface MetricsViewBeaconPluginContext {
|
|
47
|
+
/** Represents the time taken before the view is first rendered */
|
|
48
|
+
renderTime?: number;
|
|
49
|
+
/** request time */
|
|
50
|
+
requestTime?: number;
|
|
51
|
+
}
|
|
52
|
+
/** Simple [BeaconPluginPlugin] that adds renderTime to 'viewed' beacons data */
|
|
53
|
+
declare class MetricsViewBeaconPlugin implements BeaconPluginPlugin {
|
|
54
|
+
static Symbol: symbol;
|
|
55
|
+
readonly symbol: symbol;
|
|
56
|
+
private metricsPlugin;
|
|
57
|
+
private resolvePendingRenderTime;
|
|
58
|
+
constructor(metricsPlugin: MetricsCorePlugin);
|
|
59
|
+
apply(beaconPlugin: BeaconPlugin): void;
|
|
60
|
+
private buildContext;
|
|
61
|
+
private getRenderTime;
|
|
62
|
+
private getRequestTime;
|
|
63
|
+
}
|
|
64
|
+
interface MetricsWebPluginOptions {
|
|
65
|
+
/** Called when a flow starts */
|
|
66
|
+
onFlowBegin?: (update: PlayerFlowMetrics) => void;
|
|
67
|
+
/** Called when a flow ends */
|
|
68
|
+
onFlowEnd?: (update: PlayerFlowMetrics) => void;
|
|
69
|
+
/** Called when a flow becomes interactive for the first time */
|
|
70
|
+
onInteractive?: (timing: Timing, update: PlayerFlowMetrics) => void;
|
|
71
|
+
/** Called when a new node is started */
|
|
72
|
+
onNodeStart?: (nodeMetrics: NodeMetrics | NodeRenderMetrics, update: PlayerFlowMetrics) => void;
|
|
73
|
+
/** Called when a node is ended */
|
|
74
|
+
onNodeEnd?: (nodeMetrics: NodeMetrics | NodeRenderMetrics, update: PlayerFlowMetrics) => void;
|
|
75
|
+
/** Called when rendering for a node begins */
|
|
76
|
+
onRenderStart?: (timing: Timing, nodeMetrics: NodeRenderMetrics, update: PlayerFlowMetrics) => void;
|
|
77
|
+
/** Called when rendering for a node ends */
|
|
78
|
+
onRenderEnd?: (timing: Timing, nodeMetrics: NodeRenderMetrics, update: PlayerFlowMetrics) => void;
|
|
79
|
+
/** Called when an update for a node begins */
|
|
80
|
+
onUpdateStart?: (timing: Timing, nodeMetrics: NodeRenderMetrics, update: PlayerFlowMetrics) => void;
|
|
81
|
+
/** Called when an update for a node ends */
|
|
82
|
+
onUpdateEnd?: (timing: Timing, nodeMetrics: NodeRenderMetrics, update: PlayerFlowMetrics) => void;
|
|
83
|
+
/** Callback to subscribe to updates for any metric */
|
|
84
|
+
onUpdate?: (metrics: PlayerFlowMetrics) => void;
|
|
85
|
+
/**
|
|
86
|
+
* A flag to set if you want to track render times for nodes
|
|
87
|
+
* This requires that the UI calls `renderEnd()` when the view is painted.
|
|
88
|
+
*/
|
|
89
|
+
trackRenderTime?: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* A flag to set if you want to track update times for nodes
|
|
92
|
+
* This requires that the UI calls `renderEnd()` when the view is painted.
|
|
93
|
+
*/
|
|
94
|
+
trackUpdateTime?: boolean;
|
|
95
|
+
/** A function to get the current time (in ms) */
|
|
96
|
+
getTime?: () => number;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* A plugin that enables request time metrics
|
|
100
|
+
*/
|
|
101
|
+
declare class RequestTimeWebPlugin {
|
|
102
|
+
getRequestTime: () => number | undefined;
|
|
103
|
+
name: string;
|
|
104
|
+
constructor(getRequestTime: () => number | undefined);
|
|
105
|
+
apply(metricsCorePlugin: MetricsCorePlugin): void;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* A plugin that enables gathering of render metrics
|
|
109
|
+
*/
|
|
110
|
+
declare class MetricsCorePlugin implements PlayerPlugin {
|
|
111
|
+
name: string;
|
|
112
|
+
static Symbol: symbol;
|
|
113
|
+
readonly symbol: symbol;
|
|
114
|
+
protected trackRender: boolean;
|
|
115
|
+
protected trackUpdate: boolean;
|
|
116
|
+
protected getTime: () => number;
|
|
117
|
+
readonly hooks: {
|
|
118
|
+
resolveRequestTime: SyncBailHook<number, any, any, any>;
|
|
119
|
+
onFlowBegin: SyncHook<PlayerFlowMetrics, any, any>;
|
|
120
|
+
onFlowEnd: SyncHook<PlayerFlowMetrics, any, any>;
|
|
121
|
+
onInteractive: SyncHook<Timing, PlayerFlowMetrics, any>;
|
|
122
|
+
onNodeStart: SyncHook<NodeMetrics | NodeRenderMetrics, any, any>;
|
|
123
|
+
onNodeEnd: SyncHook<NodeMetrics | NodeRenderMetrics, any, any>;
|
|
124
|
+
onRenderStart: SyncHook<Timing, NodeRenderMetrics, PlayerFlowMetrics>;
|
|
125
|
+
onRenderEnd: SyncHook<Timing, NodeRenderMetrics, PlayerFlowMetrics>;
|
|
126
|
+
onUpdateStart: SyncHook<Timing, NodeRenderMetrics, PlayerFlowMetrics>;
|
|
127
|
+
onUpdateEnd: SyncHook<Timing, NodeRenderMetrics, PlayerFlowMetrics>;
|
|
128
|
+
onUpdate: SyncHook<PlayerFlowMetrics, any, any>;
|
|
129
|
+
};
|
|
130
|
+
private metrics;
|
|
131
|
+
constructor(options?: MetricsWebPluginOptions);
|
|
132
|
+
/**
|
|
133
|
+
* Fetch the metrics of the current flow
|
|
134
|
+
*/
|
|
135
|
+
getMetrics(): PlayerFlowMetrics;
|
|
136
|
+
/** Called when the UI layer wishes to start a timer for rendering */
|
|
137
|
+
private renderStart;
|
|
138
|
+
/** Called when the UI layer wants to end the rendering timer */
|
|
139
|
+
renderEnd(): void;
|
|
140
|
+
apply(player: Player): void;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
declare const MetricsCorePluginSymbol: unique symbol;
|
|
144
|
+
declare const MetricsViewBeaconPluginContextSymbol: unique symbol;
|
|
145
|
+
|
|
146
|
+
export { MetricsCorePlugin, MetricsCorePluginSymbol, MetricsViewBeaconPlugin, MetricsViewBeaconPluginContext, MetricsViewBeaconPluginContextSymbol, MetricsWebPluginOptions, NodeMetrics, NodeRenderMetrics, PlayerFlowMetrics, RequestTimeWebPlugin, Timing, defaultGetTime };
|