@player-ui/metrics-plugin 0.8.0--canary.307.9645 → 0.8.0-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/MetricsPlugin.native.js +8078 -0
- package/dist/MetricsPlugin.native.js.map +1 -0
- package/dist/{index.cjs.js → cjs/index.cjs} +137 -124
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/{index.esm.js → index.legacy-esm.js} +96 -106
- package/dist/index.mjs +330 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +23 -60
- package/src/index.test.ts +271 -0
- package/src/index.ts +2 -2
- package/src/metrics.ts +35 -35
- package/src/symbols.ts +2 -2
- package/types/index.d.ts +3 -0
- package/{dist/index.d.ts → types/metrics.d.ts} +16 -19
- package/types/symbols.d.ts +3 -0
- package/dist/metrics-plugin.dev.js +0 -11110
- package/dist/metrics-plugin.prod.js +0 -2
|
@@ -1,50 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
// ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/metrics/core/src/metrics.ts
|
|
2
|
+
import { SyncHook, SyncBailHook } from "tapable-ts";
|
|
3
|
+
import { BeaconPlugin } from "@player-ui/beacon-plugin";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
// ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/metrics/core/src/symbols.ts
|
|
6
|
+
var MetricsCorePluginSymbol = Symbol.for("MetricsCorePlugin");
|
|
7
|
+
var MetricsViewBeaconPluginContextSymbol = Symbol.for(
|
|
8
|
+
"MetricsViewBeaconPluginContext"
|
|
9
|
+
);
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
11
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
13
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
14
|
-
var __spreadValues = (a, b) => {
|
|
15
|
-
for (var prop in b || (b = {}))
|
|
16
|
-
if (__hasOwnProp.call(b, prop))
|
|
17
|
-
__defNormalProp(a, prop, b[prop]);
|
|
18
|
-
if (__getOwnPropSymbols)
|
|
19
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
20
|
-
if (__propIsEnum.call(b, prop))
|
|
21
|
-
__defNormalProp(a, prop, b[prop]);
|
|
22
|
-
}
|
|
23
|
-
return a;
|
|
24
|
-
};
|
|
25
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
26
|
-
var __async = (__this, __arguments, generator) => {
|
|
27
|
-
return new Promise((resolve, reject) => {
|
|
28
|
-
var fulfilled = (value) => {
|
|
29
|
-
try {
|
|
30
|
-
step(generator.next(value));
|
|
31
|
-
} catch (e) {
|
|
32
|
-
reject(e);
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
var rejected = (value) => {
|
|
36
|
-
try {
|
|
37
|
-
step(generator.throw(value));
|
|
38
|
-
} catch (e) {
|
|
39
|
-
reject(e);
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
43
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
44
|
-
});
|
|
45
|
-
};
|
|
46
|
-
const defaultGetTime = typeof performance === "undefined" ? () => Date.now() : () => performance.now();
|
|
47
|
-
const callbacks = [
|
|
11
|
+
// ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/metrics/core/src/metrics.ts
|
|
12
|
+
var defaultGetTime = typeof performance === "undefined" ? () => Date.now() : () => performance.now();
|
|
13
|
+
var callbacks = [
|
|
48
14
|
"onFlowBegin",
|
|
49
15
|
"onFlowEnd",
|
|
50
16
|
"onInteractive",
|
|
@@ -56,16 +22,19 @@ const callbacks = [
|
|
|
56
22
|
"onUpdateEnd",
|
|
57
23
|
"onUpdate"
|
|
58
24
|
];
|
|
59
|
-
|
|
25
|
+
var _MetricsViewBeaconPlugin = class _MetricsViewBeaconPlugin {
|
|
60
26
|
constructor(metricsPlugin) {
|
|
61
27
|
this.symbol = _MetricsViewBeaconPlugin.Symbol;
|
|
62
28
|
this.metricsPlugin = metricsPlugin;
|
|
63
|
-
this.metricsPlugin.hooks.onRenderEnd.tap(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
this.resolvePendingRenderTime
|
|
29
|
+
this.metricsPlugin.hooks.onRenderEnd.tap(
|
|
30
|
+
"MetricsViewBeaconPlugin",
|
|
31
|
+
(timing) => {
|
|
32
|
+
if (timing.completed && this.resolvePendingRenderTime) {
|
|
33
|
+
this.resolvePendingRenderTime(timing.duration);
|
|
34
|
+
this.resolvePendingRenderTime = void 0;
|
|
35
|
+
}
|
|
67
36
|
}
|
|
68
|
-
|
|
37
|
+
);
|
|
69
38
|
}
|
|
70
39
|
apply(beaconPlugin) {
|
|
71
40
|
beaconPlugin.hooks.buildBeacon.intercept({
|
|
@@ -77,36 +46,32 @@ const _MetricsViewBeaconPlugin = class {
|
|
|
77
46
|
}
|
|
78
47
|
});
|
|
79
48
|
}
|
|
80
|
-
buildContext() {
|
|
81
|
-
return
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
};
|
|
86
|
-
});
|
|
49
|
+
async buildContext() {
|
|
50
|
+
return {
|
|
51
|
+
renderTime: await this.getRenderTime(),
|
|
52
|
+
requestTime: this.getRequestTime()
|
|
53
|
+
};
|
|
87
54
|
}
|
|
88
|
-
getRenderTime() {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return lastItem.render.duration;
|
|
95
|
-
}
|
|
55
|
+
async getRenderTime() {
|
|
56
|
+
const { flow } = this.metricsPlugin.getMetrics();
|
|
57
|
+
if (flow) {
|
|
58
|
+
const lastItem = flow.timeline[flow.timeline.length - 1];
|
|
59
|
+
if ("render" in lastItem && lastItem.render.completed) {
|
|
60
|
+
return lastItem.render.duration;
|
|
96
61
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
62
|
+
}
|
|
63
|
+
return new Promise((resolve) => {
|
|
64
|
+
this.resolvePendingRenderTime = resolve;
|
|
100
65
|
});
|
|
101
66
|
}
|
|
102
67
|
getRequestTime() {
|
|
103
68
|
const { flow } = this.metricsPlugin.getMetrics();
|
|
104
|
-
return flow
|
|
69
|
+
return flow?.requestTime;
|
|
105
70
|
}
|
|
106
71
|
};
|
|
107
|
-
|
|
108
|
-
MetricsViewBeaconPlugin
|
|
109
|
-
|
|
72
|
+
_MetricsViewBeaconPlugin.Symbol = MetricsViewBeaconPluginContextSymbol;
|
|
73
|
+
var MetricsViewBeaconPlugin = _MetricsViewBeaconPlugin;
|
|
74
|
+
var RequestTimeWebPlugin = class {
|
|
110
75
|
constructor(getRequestTime) {
|
|
111
76
|
this.name = "RequestTimeWebPlugin";
|
|
112
77
|
this.getRequestTime = getRequestTime;
|
|
@@ -116,8 +81,8 @@ class RequestTimeWebPlugin {
|
|
|
116
81
|
return this.getRequestTime();
|
|
117
82
|
});
|
|
118
83
|
}
|
|
119
|
-
}
|
|
120
|
-
|
|
84
|
+
};
|
|
85
|
+
var MetricsCorePlugin = class {
|
|
121
86
|
constructor(options) {
|
|
122
87
|
this.name = "metrics";
|
|
123
88
|
this.symbol = MetricsCorePluginSymbol;
|
|
@@ -135,10 +100,9 @@ class MetricsCorePlugin {
|
|
|
135
100
|
onUpdate: new SyncHook()
|
|
136
101
|
};
|
|
137
102
|
this.metrics = {};
|
|
138
|
-
|
|
139
|
-
this.
|
|
140
|
-
this.
|
|
141
|
-
this.getTime = (_c = options == null ? void 0 : options.getTime) != null ? _c : defaultGetTime;
|
|
103
|
+
this.trackRender = options?.trackRenderTime ?? false;
|
|
104
|
+
this.trackUpdate = options?.trackUpdateTime ?? false;
|
|
105
|
+
this.getTime = options?.getTime ?? defaultGetTime;
|
|
142
106
|
const callOnUpdate = () => {
|
|
143
107
|
this.hooks.onUpdate.call(this.metrics);
|
|
144
108
|
};
|
|
@@ -152,17 +116,20 @@ class MetricsCorePlugin {
|
|
|
152
116
|
this.hooks.onUpdateStart.tap(this.name, callOnUpdate);
|
|
153
117
|
this.hooks.onUpdateEnd.tap(this.name, callOnUpdate);
|
|
154
118
|
callbacks.forEach((hookName) => {
|
|
155
|
-
if (
|
|
156
|
-
this.hooks[hookName].tap("options", options
|
|
119
|
+
if (options?.[hookName] !== void 0) {
|
|
120
|
+
this.hooks[hookName].tap("options", options?.[hookName]);
|
|
157
121
|
}
|
|
158
122
|
});
|
|
159
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Fetch the metrics of the current flow
|
|
126
|
+
*/
|
|
160
127
|
getMetrics() {
|
|
161
128
|
return this.metrics;
|
|
162
129
|
}
|
|
130
|
+
/** Called when the UI layer wishes to start a timer for rendering */
|
|
163
131
|
renderStart() {
|
|
164
|
-
|
|
165
|
-
const timeline = (_a = this.metrics.flow) == null ? void 0 : _a.timeline;
|
|
132
|
+
const timeline = this.metrics.flow?.timeline;
|
|
166
133
|
if (!timeline || timeline.length === 0) {
|
|
167
134
|
return;
|
|
168
135
|
}
|
|
@@ -184,20 +151,28 @@ class MetricsCorePlugin {
|
|
|
184
151
|
lastItem.updates.push(update);
|
|
185
152
|
this.hooks.onUpdateStart.call(update, lastItem, this.metrics);
|
|
186
153
|
} else {
|
|
187
|
-
const renderInfo =
|
|
154
|
+
const renderInfo = {
|
|
155
|
+
...lastItem,
|
|
188
156
|
render: {
|
|
189
157
|
completed: false,
|
|
190
158
|
startTime: defaultGetTime()
|
|
191
159
|
},
|
|
192
160
|
updates: []
|
|
193
|
-
}
|
|
161
|
+
};
|
|
194
162
|
timeline[timeline.length - 1] = renderInfo;
|
|
195
|
-
this.hooks.onRenderStart.call(
|
|
163
|
+
this.hooks.onRenderStart.call(
|
|
164
|
+
renderInfo.render,
|
|
165
|
+
renderInfo,
|
|
166
|
+
this.metrics
|
|
167
|
+
);
|
|
196
168
|
}
|
|
197
169
|
}
|
|
170
|
+
/** Called when the UI layer wants to end the rendering timer */
|
|
198
171
|
renderEnd() {
|
|
199
172
|
if (!this.trackRender) {
|
|
200
|
-
throw new Error(
|
|
173
|
+
throw new Error(
|
|
174
|
+
"Must start the metrics-plugin with render tracking enabled"
|
|
175
|
+
);
|
|
201
176
|
}
|
|
202
177
|
const { flow } = this.metrics;
|
|
203
178
|
if (!flow) {
|
|
@@ -220,26 +195,29 @@ class MetricsCorePlugin {
|
|
|
220
195
|
if (lastUpdate.completed === true) {
|
|
221
196
|
return;
|
|
222
197
|
}
|
|
223
|
-
const update =
|
|
198
|
+
const update = {
|
|
199
|
+
...lastUpdate,
|
|
224
200
|
completed: true,
|
|
225
201
|
endTime,
|
|
226
202
|
duration: endTime - lastUpdate.startTime
|
|
227
|
-
}
|
|
203
|
+
};
|
|
228
204
|
lastItem.updates[lastItem.updates.length - 1] = update;
|
|
229
205
|
this.hooks.onUpdateEnd.call(update, lastItem, this.metrics);
|
|
230
206
|
} else {
|
|
231
|
-
lastItem.render =
|
|
207
|
+
lastItem.render = {
|
|
208
|
+
...lastItem.render,
|
|
232
209
|
completed: true,
|
|
233
210
|
endTime,
|
|
234
211
|
duration: endTime - lastItem.startTime
|
|
235
|
-
}
|
|
212
|
+
};
|
|
236
213
|
this.hooks.onRenderEnd.call(lastItem.render, lastItem, this.metrics);
|
|
237
214
|
if (!interactive.completed) {
|
|
238
|
-
flow.interactive =
|
|
215
|
+
flow.interactive = {
|
|
216
|
+
...interactive,
|
|
239
217
|
completed: true,
|
|
240
218
|
duration: endTime - interactive.startTime,
|
|
241
219
|
endTime
|
|
242
|
-
}
|
|
220
|
+
};
|
|
243
221
|
this.hooks.onInteractive.call(flow.interactive, this.metrics);
|
|
244
222
|
}
|
|
245
223
|
}
|
|
@@ -251,7 +229,7 @@ class MetricsCorePlugin {
|
|
|
251
229
|
this.metrics = {
|
|
252
230
|
flow: {
|
|
253
231
|
id: flow.id,
|
|
254
|
-
requestTime: requestTime
|
|
232
|
+
requestTime: requestTime ?? void 0,
|
|
255
233
|
timeline: [],
|
|
256
234
|
startTime,
|
|
257
235
|
completed: false,
|
|
@@ -267,23 +245,25 @@ class MetricsCorePlugin {
|
|
|
267
245
|
if (state.status === "completed" || state.status === "error") {
|
|
268
246
|
const endTime = defaultGetTime();
|
|
269
247
|
const { flow } = this.metrics;
|
|
270
|
-
if (flow === void 0 ||
|
|
248
|
+
if (flow === void 0 || flow?.completed === true) {
|
|
271
249
|
return;
|
|
272
250
|
}
|
|
273
251
|
this.metrics = {
|
|
274
|
-
flow:
|
|
252
|
+
flow: {
|
|
253
|
+
...flow,
|
|
275
254
|
completed: true,
|
|
276
255
|
endTime,
|
|
277
256
|
duration: endTime - flow.startTime
|
|
278
|
-
}
|
|
257
|
+
}
|
|
279
258
|
};
|
|
280
259
|
const lastUpdate = flow.timeline[flow.timeline.length - 1];
|
|
281
260
|
if (lastUpdate && !lastUpdate.completed) {
|
|
282
|
-
this.metrics.flow.timeline[flow.timeline.length - 1] =
|
|
261
|
+
this.metrics.flow.timeline[flow.timeline.length - 1] = {
|
|
262
|
+
...lastUpdate,
|
|
283
263
|
completed: true,
|
|
284
264
|
endTime,
|
|
285
265
|
duration: endTime - lastUpdate.startTime
|
|
286
|
-
}
|
|
266
|
+
};
|
|
287
267
|
}
|
|
288
268
|
this.hooks.onFlowEnd.call(this.metrics);
|
|
289
269
|
}
|
|
@@ -302,11 +282,12 @@ class MetricsCorePlugin {
|
|
|
302
282
|
if (prev.completed) {
|
|
303
283
|
throw new Error("Completing a state that's already done.");
|
|
304
284
|
}
|
|
305
|
-
timeline[timeline.length - 1] =
|
|
285
|
+
timeline[timeline.length - 1] = {
|
|
286
|
+
...prev,
|
|
306
287
|
completed: true,
|
|
307
288
|
endTime: time,
|
|
308
289
|
duration: time - prev.startTime
|
|
309
|
-
}
|
|
290
|
+
};
|
|
310
291
|
this.hooks.onNodeEnd.call(timeline[timeline.length - 1]);
|
|
311
292
|
}
|
|
312
293
|
const nodeMetrics = {
|
|
@@ -330,11 +311,20 @@ class MetricsCorePlugin {
|
|
|
330
311
|
this.renderStart();
|
|
331
312
|
}
|
|
332
313
|
});
|
|
333
|
-
player.applyTo(
|
|
314
|
+
player.applyTo(
|
|
315
|
+
BeaconPlugin.Symbol,
|
|
316
|
+
(beaconPlugin) => new MetricsViewBeaconPlugin(this).apply(beaconPlugin)
|
|
317
|
+
);
|
|
334
318
|
}
|
|
335
319
|
}
|
|
336
|
-
}
|
|
320
|
+
};
|
|
337
321
|
MetricsCorePlugin.Symbol = MetricsCorePluginSymbol;
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
322
|
+
export {
|
|
323
|
+
MetricsCorePlugin,
|
|
324
|
+
MetricsCorePluginSymbol,
|
|
325
|
+
MetricsViewBeaconPlugin,
|
|
326
|
+
MetricsViewBeaconPluginContextSymbol,
|
|
327
|
+
RequestTimeWebPlugin,
|
|
328
|
+
defaultGetTime
|
|
329
|
+
};
|
|
330
|
+
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
// ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/metrics/core/src/metrics.ts
|
|
2
|
+
import { SyncHook, SyncBailHook } from "tapable-ts";
|
|
3
|
+
import { BeaconPlugin } from "@player-ui/beacon-plugin";
|
|
4
|
+
|
|
5
|
+
// ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/metrics/core/src/symbols.ts
|
|
6
|
+
var MetricsCorePluginSymbol = Symbol.for("MetricsCorePlugin");
|
|
7
|
+
var MetricsViewBeaconPluginContextSymbol = Symbol.for(
|
|
8
|
+
"MetricsViewBeaconPluginContext"
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
// ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/metrics/core/src/metrics.ts
|
|
12
|
+
var defaultGetTime = typeof performance === "undefined" ? () => Date.now() : () => performance.now();
|
|
13
|
+
var callbacks = [
|
|
14
|
+
"onFlowBegin",
|
|
15
|
+
"onFlowEnd",
|
|
16
|
+
"onInteractive",
|
|
17
|
+
"onNodeStart",
|
|
18
|
+
"onNodeEnd",
|
|
19
|
+
"onRenderStart",
|
|
20
|
+
"onRenderEnd",
|
|
21
|
+
"onUpdateStart",
|
|
22
|
+
"onUpdateEnd",
|
|
23
|
+
"onUpdate"
|
|
24
|
+
];
|
|
25
|
+
var _MetricsViewBeaconPlugin = class _MetricsViewBeaconPlugin {
|
|
26
|
+
constructor(metricsPlugin) {
|
|
27
|
+
this.symbol = _MetricsViewBeaconPlugin.Symbol;
|
|
28
|
+
this.metricsPlugin = metricsPlugin;
|
|
29
|
+
this.metricsPlugin.hooks.onRenderEnd.tap(
|
|
30
|
+
"MetricsViewBeaconPlugin",
|
|
31
|
+
(timing) => {
|
|
32
|
+
if (timing.completed && this.resolvePendingRenderTime) {
|
|
33
|
+
this.resolvePendingRenderTime(timing.duration);
|
|
34
|
+
this.resolvePendingRenderTime = void 0;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
apply(beaconPlugin) {
|
|
40
|
+
beaconPlugin.hooks.buildBeacon.intercept({
|
|
41
|
+
context: true,
|
|
42
|
+
call: (context, beacon) => {
|
|
43
|
+
if (context && beacon.action === "viewed") {
|
|
44
|
+
context[this.symbol] = this.buildContext();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
async buildContext() {
|
|
50
|
+
return {
|
|
51
|
+
renderTime: await this.getRenderTime(),
|
|
52
|
+
requestTime: this.getRequestTime()
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
async getRenderTime() {
|
|
56
|
+
const { flow } = this.metricsPlugin.getMetrics();
|
|
57
|
+
if (flow) {
|
|
58
|
+
const lastItem = flow.timeline[flow.timeline.length - 1];
|
|
59
|
+
if ("render" in lastItem && lastItem.render.completed) {
|
|
60
|
+
return lastItem.render.duration;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return new Promise((resolve) => {
|
|
64
|
+
this.resolvePendingRenderTime = resolve;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
getRequestTime() {
|
|
68
|
+
const { flow } = this.metricsPlugin.getMetrics();
|
|
69
|
+
return flow?.requestTime;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
_MetricsViewBeaconPlugin.Symbol = MetricsViewBeaconPluginContextSymbol;
|
|
73
|
+
var MetricsViewBeaconPlugin = _MetricsViewBeaconPlugin;
|
|
74
|
+
var RequestTimeWebPlugin = class {
|
|
75
|
+
constructor(getRequestTime) {
|
|
76
|
+
this.name = "RequestTimeWebPlugin";
|
|
77
|
+
this.getRequestTime = getRequestTime;
|
|
78
|
+
}
|
|
79
|
+
apply(metricsCorePlugin) {
|
|
80
|
+
metricsCorePlugin.hooks.resolveRequestTime.tap(this.name, () => {
|
|
81
|
+
return this.getRequestTime();
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
var MetricsCorePlugin = class {
|
|
86
|
+
constructor(options) {
|
|
87
|
+
this.name = "metrics";
|
|
88
|
+
this.symbol = MetricsCorePluginSymbol;
|
|
89
|
+
this.hooks = {
|
|
90
|
+
resolveRequestTime: new SyncBailHook(),
|
|
91
|
+
onFlowBegin: new SyncHook(),
|
|
92
|
+
onFlowEnd: new SyncHook(),
|
|
93
|
+
onInteractive: new SyncHook(),
|
|
94
|
+
onNodeStart: new SyncHook(),
|
|
95
|
+
onNodeEnd: new SyncHook(),
|
|
96
|
+
onRenderStart: new SyncHook(),
|
|
97
|
+
onRenderEnd: new SyncHook(),
|
|
98
|
+
onUpdateStart: new SyncHook(),
|
|
99
|
+
onUpdateEnd: new SyncHook(),
|
|
100
|
+
onUpdate: new SyncHook()
|
|
101
|
+
};
|
|
102
|
+
this.metrics = {};
|
|
103
|
+
this.trackRender = options?.trackRenderTime ?? false;
|
|
104
|
+
this.trackUpdate = options?.trackUpdateTime ?? false;
|
|
105
|
+
this.getTime = options?.getTime ?? defaultGetTime;
|
|
106
|
+
const callOnUpdate = () => {
|
|
107
|
+
this.hooks.onUpdate.call(this.metrics);
|
|
108
|
+
};
|
|
109
|
+
this.hooks.onFlowBegin.tap(this.name, callOnUpdate);
|
|
110
|
+
this.hooks.onFlowEnd.tap(this.name, callOnUpdate);
|
|
111
|
+
this.hooks.onInteractive.tap(this.name, callOnUpdate);
|
|
112
|
+
this.hooks.onNodeStart.tap(this.name, callOnUpdate);
|
|
113
|
+
this.hooks.onNodeEnd.tap(this.name, callOnUpdate);
|
|
114
|
+
this.hooks.onRenderStart.tap(this.name, callOnUpdate);
|
|
115
|
+
this.hooks.onRenderEnd.tap(this.name, callOnUpdate);
|
|
116
|
+
this.hooks.onUpdateStart.tap(this.name, callOnUpdate);
|
|
117
|
+
this.hooks.onUpdateEnd.tap(this.name, callOnUpdate);
|
|
118
|
+
callbacks.forEach((hookName) => {
|
|
119
|
+
if (options?.[hookName] !== void 0) {
|
|
120
|
+
this.hooks[hookName].tap("options", options?.[hookName]);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Fetch the metrics of the current flow
|
|
126
|
+
*/
|
|
127
|
+
getMetrics() {
|
|
128
|
+
return this.metrics;
|
|
129
|
+
}
|
|
130
|
+
/** Called when the UI layer wishes to start a timer for rendering */
|
|
131
|
+
renderStart() {
|
|
132
|
+
const timeline = this.metrics.flow?.timeline;
|
|
133
|
+
if (!timeline || timeline.length === 0) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const lastItem = timeline[timeline.length - 1];
|
|
137
|
+
if ("updates" in lastItem) {
|
|
138
|
+
if (lastItem.updates.length > 0) {
|
|
139
|
+
const lastUpdate = lastItem.updates[lastItem.updates.length - 1];
|
|
140
|
+
if (lastUpdate.completed === false) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (!lastItem.render.completed) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const update = {
|
|
148
|
+
completed: false,
|
|
149
|
+
startTime: defaultGetTime()
|
|
150
|
+
};
|
|
151
|
+
lastItem.updates.push(update);
|
|
152
|
+
this.hooks.onUpdateStart.call(update, lastItem, this.metrics);
|
|
153
|
+
} else {
|
|
154
|
+
const renderInfo = {
|
|
155
|
+
...lastItem,
|
|
156
|
+
render: {
|
|
157
|
+
completed: false,
|
|
158
|
+
startTime: defaultGetTime()
|
|
159
|
+
},
|
|
160
|
+
updates: []
|
|
161
|
+
};
|
|
162
|
+
timeline[timeline.length - 1] = renderInfo;
|
|
163
|
+
this.hooks.onRenderStart.call(
|
|
164
|
+
renderInfo.render,
|
|
165
|
+
renderInfo,
|
|
166
|
+
this.metrics
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/** Called when the UI layer wants to end the rendering timer */
|
|
171
|
+
renderEnd() {
|
|
172
|
+
if (!this.trackRender) {
|
|
173
|
+
throw new Error(
|
|
174
|
+
"Must start the metrics-plugin with render tracking enabled"
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
const { flow } = this.metrics;
|
|
178
|
+
if (!flow) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const { timeline, interactive } = flow;
|
|
182
|
+
if (!timeline || !interactive || timeline.length === 0) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const lastItem = timeline[timeline.length - 1];
|
|
186
|
+
if (!("render" in lastItem)) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const endTime = defaultGetTime();
|
|
190
|
+
if (lastItem.render.completed) {
|
|
191
|
+
if (lastItem.updates.length === 0) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const lastUpdate = lastItem.updates[lastItem.updates.length - 1];
|
|
195
|
+
if (lastUpdate.completed === true) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const update = {
|
|
199
|
+
...lastUpdate,
|
|
200
|
+
completed: true,
|
|
201
|
+
endTime,
|
|
202
|
+
duration: endTime - lastUpdate.startTime
|
|
203
|
+
};
|
|
204
|
+
lastItem.updates[lastItem.updates.length - 1] = update;
|
|
205
|
+
this.hooks.onUpdateEnd.call(update, lastItem, this.metrics);
|
|
206
|
+
} else {
|
|
207
|
+
lastItem.render = {
|
|
208
|
+
...lastItem.render,
|
|
209
|
+
completed: true,
|
|
210
|
+
endTime,
|
|
211
|
+
duration: endTime - lastItem.startTime
|
|
212
|
+
};
|
|
213
|
+
this.hooks.onRenderEnd.call(lastItem.render, lastItem, this.metrics);
|
|
214
|
+
if (!interactive.completed) {
|
|
215
|
+
flow.interactive = {
|
|
216
|
+
...interactive,
|
|
217
|
+
completed: true,
|
|
218
|
+
duration: endTime - interactive.startTime,
|
|
219
|
+
endTime
|
|
220
|
+
};
|
|
221
|
+
this.hooks.onInteractive.call(flow.interactive, this.metrics);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
apply(player) {
|
|
226
|
+
player.hooks.onStart.tap(this.name, (flow) => {
|
|
227
|
+
const requestTime = this.hooks.resolveRequestTime.call();
|
|
228
|
+
const startTime = defaultGetTime();
|
|
229
|
+
this.metrics = {
|
|
230
|
+
flow: {
|
|
231
|
+
id: flow.id,
|
|
232
|
+
requestTime: requestTime ?? void 0,
|
|
233
|
+
timeline: [],
|
|
234
|
+
startTime,
|
|
235
|
+
completed: false,
|
|
236
|
+
interactive: {
|
|
237
|
+
completed: false,
|
|
238
|
+
startTime
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
this.hooks.onFlowBegin.call(this.metrics);
|
|
243
|
+
});
|
|
244
|
+
player.hooks.state.tap(this.name, (state) => {
|
|
245
|
+
if (state.status === "completed" || state.status === "error") {
|
|
246
|
+
const endTime = defaultGetTime();
|
|
247
|
+
const { flow } = this.metrics;
|
|
248
|
+
if (flow === void 0 || flow?.completed === true) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
this.metrics = {
|
|
252
|
+
flow: {
|
|
253
|
+
...flow,
|
|
254
|
+
completed: true,
|
|
255
|
+
endTime,
|
|
256
|
+
duration: endTime - flow.startTime
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
const lastUpdate = flow.timeline[flow.timeline.length - 1];
|
|
260
|
+
if (lastUpdate && !lastUpdate.completed) {
|
|
261
|
+
this.metrics.flow.timeline[flow.timeline.length - 1] = {
|
|
262
|
+
...lastUpdate,
|
|
263
|
+
completed: true,
|
|
264
|
+
endTime,
|
|
265
|
+
duration: endTime - lastUpdate.startTime
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
this.hooks.onFlowEnd.call(this.metrics);
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
player.hooks.flowController.tap(this.name, (fc) => {
|
|
272
|
+
fc.hooks.flow.tap(this.name, (f) => {
|
|
273
|
+
f.hooks.transition.tap(this.name, (from, to) => {
|
|
274
|
+
const time = defaultGetTime();
|
|
275
|
+
const { flow } = this.metrics;
|
|
276
|
+
if (!flow) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const { timeline } = flow;
|
|
280
|
+
if (timeline.length > 0) {
|
|
281
|
+
const prev = timeline[timeline.length - 1];
|
|
282
|
+
if (prev.completed) {
|
|
283
|
+
throw new Error("Completing a state that's already done.");
|
|
284
|
+
}
|
|
285
|
+
timeline[timeline.length - 1] = {
|
|
286
|
+
...prev,
|
|
287
|
+
completed: true,
|
|
288
|
+
endTime: time,
|
|
289
|
+
duration: time - prev.startTime
|
|
290
|
+
};
|
|
291
|
+
this.hooks.onNodeEnd.call(timeline[timeline.length - 1]);
|
|
292
|
+
}
|
|
293
|
+
const nodeMetrics = {
|
|
294
|
+
completed: false,
|
|
295
|
+
startTime: time,
|
|
296
|
+
stateName: to.name,
|
|
297
|
+
stateType: to.value.state_type
|
|
298
|
+
};
|
|
299
|
+
timeline.push(nodeMetrics);
|
|
300
|
+
this.hooks.onNodeStart.call(nodeMetrics);
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
if (this.trackRender) {
|
|
305
|
+
player.hooks.view.tap(this.name, (v) => {
|
|
306
|
+
if (this.trackUpdate) {
|
|
307
|
+
v.hooks.onUpdate.tap(this.name, () => {
|
|
308
|
+
this.renderStart();
|
|
309
|
+
});
|
|
310
|
+
} else {
|
|
311
|
+
this.renderStart();
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
player.applyTo(
|
|
315
|
+
BeaconPlugin.Symbol,
|
|
316
|
+
(beaconPlugin) => new MetricsViewBeaconPlugin(this).apply(beaconPlugin)
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
MetricsCorePlugin.Symbol = MetricsCorePluginSymbol;
|
|
322
|
+
export {
|
|
323
|
+
MetricsCorePlugin,
|
|
324
|
+
MetricsCorePluginSymbol,
|
|
325
|
+
MetricsViewBeaconPlugin,
|
|
326
|
+
MetricsViewBeaconPluginContextSymbol,
|
|
327
|
+
RequestTimeWebPlugin,
|
|
328
|
+
defaultGetTime
|
|
329
|
+
};
|
|
330
|
+
//# sourceMappingURL=index.mjs.map
|