@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.
@@ -1,54 +1,47 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var tapableTs = require('tapable-ts');
6
- var beaconPlugin = require('@player-ui/beacon-plugin');
7
-
8
- const MetricsCorePluginSymbol = Symbol.for("MetricsCorePlugin");
9
- const MetricsViewBeaconPluginContextSymbol = Symbol.for("MetricsViewBeaconPluginContext");
10
-
1
+ "use strict";
11
2
  var __defProp = Object.defineProperty;
12
- var __defProps = Object.defineProperties;
13
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
14
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
15
5
  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;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
28
9
  };
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
- });
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
49
17
  };
50
- const defaultGetTime = typeof performance === "undefined" ? () => Date.now() : () => performance.now();
51
- const callbacks = [
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/metrics/core/src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ MetricsCorePlugin: () => MetricsCorePlugin,
24
+ MetricsCorePluginSymbol: () => MetricsCorePluginSymbol,
25
+ MetricsViewBeaconPlugin: () => MetricsViewBeaconPlugin,
26
+ MetricsViewBeaconPluginContextSymbol: () => MetricsViewBeaconPluginContextSymbol,
27
+ RequestTimeWebPlugin: () => RequestTimeWebPlugin,
28
+ defaultGetTime: () => defaultGetTime
29
+ });
30
+ module.exports = __toCommonJS(src_exports);
31
+
32
+ // ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/metrics/core/src/metrics.ts
33
+ var import_tapable_ts = require("tapable-ts");
34
+ var import_beacon_plugin = require("@player-ui/beacon-plugin");
35
+
36
+ // ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/metrics/core/src/symbols.ts
37
+ var MetricsCorePluginSymbol = Symbol.for("MetricsCorePlugin");
38
+ var MetricsViewBeaconPluginContextSymbol = Symbol.for(
39
+ "MetricsViewBeaconPluginContext"
40
+ );
41
+
42
+ // ../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/metrics/core/src/metrics.ts
43
+ var defaultGetTime = typeof performance === "undefined" ? () => Date.now() : () => performance.now();
44
+ var callbacks = [
52
45
  "onFlowBegin",
53
46
  "onFlowEnd",
54
47
  "onInteractive",
@@ -60,16 +53,19 @@ const callbacks = [
60
53
  "onUpdateEnd",
61
54
  "onUpdate"
62
55
  ];
63
- const _MetricsViewBeaconPlugin = class {
56
+ var _MetricsViewBeaconPlugin = class _MetricsViewBeaconPlugin {
64
57
  constructor(metricsPlugin) {
65
58
  this.symbol = _MetricsViewBeaconPlugin.Symbol;
66
59
  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;
60
+ this.metricsPlugin.hooks.onRenderEnd.tap(
61
+ "MetricsViewBeaconPlugin",
62
+ (timing) => {
63
+ if (timing.completed && this.resolvePendingRenderTime) {
64
+ this.resolvePendingRenderTime(timing.duration);
65
+ this.resolvePendingRenderTime = void 0;
66
+ }
71
67
  }
72
- });
68
+ );
73
69
  }
74
70
  apply(beaconPlugin) {
75
71
  beaconPlugin.hooks.buildBeacon.intercept({
@@ -81,36 +77,32 @@ const _MetricsViewBeaconPlugin = class {
81
77
  }
82
78
  });
83
79
  }
84
- buildContext() {
85
- return __async(this, null, function* () {
86
- return {
87
- renderTime: yield this.getRenderTime(),
88
- requestTime: this.getRequestTime()
89
- };
90
- });
80
+ async buildContext() {
81
+ return {
82
+ renderTime: await this.getRenderTime(),
83
+ requestTime: this.getRequestTime()
84
+ };
91
85
  }
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
- }
86
+ async getRenderTime() {
87
+ const { flow } = this.metricsPlugin.getMetrics();
88
+ if (flow) {
89
+ const lastItem = flow.timeline[flow.timeline.length - 1];
90
+ if ("render" in lastItem && lastItem.render.completed) {
91
+ return lastItem.render.duration;
100
92
  }
101
- return new Promise((resolve) => {
102
- this.resolvePendingRenderTime = resolve;
103
- });
93
+ }
94
+ return new Promise((resolve) => {
95
+ this.resolvePendingRenderTime = resolve;
104
96
  });
105
97
  }
106
98
  getRequestTime() {
107
99
  const { flow } = this.metricsPlugin.getMetrics();
108
- return flow == null ? void 0 : flow.requestTime;
100
+ return flow?.requestTime;
109
101
  }
110
102
  };
111
- let MetricsViewBeaconPlugin = _MetricsViewBeaconPlugin;
112
- MetricsViewBeaconPlugin.Symbol = MetricsViewBeaconPluginContextSymbol;
113
- class RequestTimeWebPlugin {
103
+ _MetricsViewBeaconPlugin.Symbol = MetricsViewBeaconPluginContextSymbol;
104
+ var MetricsViewBeaconPlugin = _MetricsViewBeaconPlugin;
105
+ var RequestTimeWebPlugin = class {
114
106
  constructor(getRequestTime) {
115
107
  this.name = "RequestTimeWebPlugin";
116
108
  this.getRequestTime = getRequestTime;
@@ -120,29 +112,28 @@ class RequestTimeWebPlugin {
120
112
  return this.getRequestTime();
121
113
  });
122
114
  }
123
- }
124
- class MetricsCorePlugin {
115
+ };
116
+ var MetricsCorePlugin = class {
125
117
  constructor(options) {
126
118
  this.name = "metrics";
127
119
  this.symbol = MetricsCorePluginSymbol;
128
120
  this.hooks = {
129
- resolveRequestTime: new tapableTs.SyncBailHook(),
130
- onFlowBegin: new tapableTs.SyncHook(),
131
- onFlowEnd: new tapableTs.SyncHook(),
132
- onInteractive: new tapableTs.SyncHook(),
133
- onNodeStart: new tapableTs.SyncHook(),
134
- onNodeEnd: new tapableTs.SyncHook(),
135
- onRenderStart: new tapableTs.SyncHook(),
136
- onRenderEnd: new tapableTs.SyncHook(),
137
- onUpdateStart: new tapableTs.SyncHook(),
138
- onUpdateEnd: new tapableTs.SyncHook(),
139
- onUpdate: new tapableTs.SyncHook()
121
+ resolveRequestTime: new import_tapable_ts.SyncBailHook(),
122
+ onFlowBegin: new import_tapable_ts.SyncHook(),
123
+ onFlowEnd: new import_tapable_ts.SyncHook(),
124
+ onInteractive: new import_tapable_ts.SyncHook(),
125
+ onNodeStart: new import_tapable_ts.SyncHook(),
126
+ onNodeEnd: new import_tapable_ts.SyncHook(),
127
+ onRenderStart: new import_tapable_ts.SyncHook(),
128
+ onRenderEnd: new import_tapable_ts.SyncHook(),
129
+ onUpdateStart: new import_tapable_ts.SyncHook(),
130
+ onUpdateEnd: new import_tapable_ts.SyncHook(),
131
+ onUpdate: new import_tapable_ts.SyncHook()
140
132
  };
141
133
  this.metrics = {};
142
- var _a, _b, _c;
143
- this.trackRender = (_a = options == null ? void 0 : options.trackRenderTime) != null ? _a : false;
144
- this.trackUpdate = (_b = options == null ? void 0 : options.trackUpdateTime) != null ? _b : false;
145
- this.getTime = (_c = options == null ? void 0 : options.getTime) != null ? _c : defaultGetTime;
134
+ this.trackRender = options?.trackRenderTime ?? false;
135
+ this.trackUpdate = options?.trackUpdateTime ?? false;
136
+ this.getTime = options?.getTime ?? defaultGetTime;
146
137
  const callOnUpdate = () => {
147
138
  this.hooks.onUpdate.call(this.metrics);
148
139
  };
@@ -156,17 +147,20 @@ class MetricsCorePlugin {
156
147
  this.hooks.onUpdateStart.tap(this.name, callOnUpdate);
157
148
  this.hooks.onUpdateEnd.tap(this.name, callOnUpdate);
158
149
  callbacks.forEach((hookName) => {
159
- if ((options == null ? void 0 : options[hookName]) !== void 0) {
160
- this.hooks[hookName].tap("options", options == null ? void 0 : options[hookName]);
150
+ if (options?.[hookName] !== void 0) {
151
+ this.hooks[hookName].tap("options", options?.[hookName]);
161
152
  }
162
153
  });
163
154
  }
155
+ /**
156
+ * Fetch the metrics of the current flow
157
+ */
164
158
  getMetrics() {
165
159
  return this.metrics;
166
160
  }
161
+ /** Called when the UI layer wishes to start a timer for rendering */
167
162
  renderStart() {
168
- var _a;
169
- const timeline = (_a = this.metrics.flow) == null ? void 0 : _a.timeline;
163
+ const timeline = this.metrics.flow?.timeline;
170
164
  if (!timeline || timeline.length === 0) {
171
165
  return;
172
166
  }
@@ -188,20 +182,28 @@ class MetricsCorePlugin {
188
182
  lastItem.updates.push(update);
189
183
  this.hooks.onUpdateStart.call(update, lastItem, this.metrics);
190
184
  } else {
191
- const renderInfo = __spreadProps(__spreadValues({}, lastItem), {
185
+ const renderInfo = {
186
+ ...lastItem,
192
187
  render: {
193
188
  completed: false,
194
189
  startTime: defaultGetTime()
195
190
  },
196
191
  updates: []
197
- });
192
+ };
198
193
  timeline[timeline.length - 1] = renderInfo;
199
- this.hooks.onRenderStart.call(renderInfo.render, renderInfo, this.metrics);
194
+ this.hooks.onRenderStart.call(
195
+ renderInfo.render,
196
+ renderInfo,
197
+ this.metrics
198
+ );
200
199
  }
201
200
  }
201
+ /** Called when the UI layer wants to end the rendering timer */
202
202
  renderEnd() {
203
203
  if (!this.trackRender) {
204
- throw new Error("Must start the metrics-plugin with render tracking enabled");
204
+ throw new Error(
205
+ "Must start the metrics-plugin with render tracking enabled"
206
+ );
205
207
  }
206
208
  const { flow } = this.metrics;
207
209
  if (!flow) {
@@ -224,26 +226,29 @@ class MetricsCorePlugin {
224
226
  if (lastUpdate.completed === true) {
225
227
  return;
226
228
  }
227
- const update = __spreadProps(__spreadValues({}, lastUpdate), {
229
+ const update = {
230
+ ...lastUpdate,
228
231
  completed: true,
229
232
  endTime,
230
233
  duration: endTime - lastUpdate.startTime
231
- });
234
+ };
232
235
  lastItem.updates[lastItem.updates.length - 1] = update;
233
236
  this.hooks.onUpdateEnd.call(update, lastItem, this.metrics);
234
237
  } else {
235
- lastItem.render = __spreadProps(__spreadValues({}, lastItem.render), {
238
+ lastItem.render = {
239
+ ...lastItem.render,
236
240
  completed: true,
237
241
  endTime,
238
242
  duration: endTime - lastItem.startTime
239
- });
243
+ };
240
244
  this.hooks.onRenderEnd.call(lastItem.render, lastItem, this.metrics);
241
245
  if (!interactive.completed) {
242
- flow.interactive = __spreadProps(__spreadValues({}, interactive), {
246
+ flow.interactive = {
247
+ ...interactive,
243
248
  completed: true,
244
249
  duration: endTime - interactive.startTime,
245
250
  endTime
246
- });
251
+ };
247
252
  this.hooks.onInteractive.call(flow.interactive, this.metrics);
248
253
  }
249
254
  }
@@ -255,7 +260,7 @@ class MetricsCorePlugin {
255
260
  this.metrics = {
256
261
  flow: {
257
262
  id: flow.id,
258
- requestTime: requestTime != null ? requestTime : void 0,
263
+ requestTime: requestTime ?? void 0,
259
264
  timeline: [],
260
265
  startTime,
261
266
  completed: false,
@@ -271,23 +276,25 @@ class MetricsCorePlugin {
271
276
  if (state.status === "completed" || state.status === "error") {
272
277
  const endTime = defaultGetTime();
273
278
  const { flow } = this.metrics;
274
- if (flow === void 0 || (flow == null ? void 0 : flow.completed) === true) {
279
+ if (flow === void 0 || flow?.completed === true) {
275
280
  return;
276
281
  }
277
282
  this.metrics = {
278
- flow: __spreadProps(__spreadValues({}, flow), {
283
+ flow: {
284
+ ...flow,
279
285
  completed: true,
280
286
  endTime,
281
287
  duration: endTime - flow.startTime
282
- })
288
+ }
283
289
  };
284
290
  const lastUpdate = flow.timeline[flow.timeline.length - 1];
285
291
  if (lastUpdate && !lastUpdate.completed) {
286
- this.metrics.flow.timeline[flow.timeline.length - 1] = __spreadProps(__spreadValues({}, lastUpdate), {
292
+ this.metrics.flow.timeline[flow.timeline.length - 1] = {
293
+ ...lastUpdate,
287
294
  completed: true,
288
295
  endTime,
289
296
  duration: endTime - lastUpdate.startTime
290
- });
297
+ };
291
298
  }
292
299
  this.hooks.onFlowEnd.call(this.metrics);
293
300
  }
@@ -306,11 +313,12 @@ class MetricsCorePlugin {
306
313
  if (prev.completed) {
307
314
  throw new Error("Completing a state that's already done.");
308
315
  }
309
- timeline[timeline.length - 1] = __spreadProps(__spreadValues({}, prev), {
316
+ timeline[timeline.length - 1] = {
317
+ ...prev,
310
318
  completed: true,
311
319
  endTime: time,
312
320
  duration: time - prev.startTime
313
- });
321
+ };
314
322
  this.hooks.onNodeEnd.call(timeline[timeline.length - 1]);
315
323
  }
316
324
  const nodeMetrics = {
@@ -334,16 +342,21 @@ class MetricsCorePlugin {
334
342
  this.renderStart();
335
343
  }
336
344
  });
337
- player.applyTo(beaconPlugin.BeaconPlugin.Symbol, (beaconPlugin) => new MetricsViewBeaconPlugin(this).apply(beaconPlugin));
345
+ player.applyTo(
346
+ import_beacon_plugin.BeaconPlugin.Symbol,
347
+ (beaconPlugin) => new MetricsViewBeaconPlugin(this).apply(beaconPlugin)
348
+ );
338
349
  }
339
350
  }
340
- }
351
+ };
341
352
  MetricsCorePlugin.Symbol = MetricsCorePluginSymbol;
342
-
343
- exports.MetricsCorePlugin = MetricsCorePlugin;
344
- exports.MetricsCorePluginSymbol = MetricsCorePluginSymbol;
345
- exports.MetricsViewBeaconPlugin = MetricsViewBeaconPlugin;
346
- exports.MetricsViewBeaconPluginContextSymbol = MetricsViewBeaconPluginContextSymbol;
347
- exports.RequestTimeWebPlugin = RequestTimeWebPlugin;
348
- exports.defaultGetTime = defaultGetTime;
349
- //# sourceMappingURL=index.cjs.js.map
353
+ // Annotate the CommonJS export names for ESM import in node:
354
+ 0 && (module.exports = {
355
+ MetricsCorePlugin,
356
+ MetricsCorePluginSymbol,
357
+ MetricsViewBeaconPlugin,
358
+ MetricsViewBeaconPluginContextSymbol,
359
+ RequestTimeWebPlugin,
360
+ defaultGetTime
361
+ });
362
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/metrics/core/src/index.ts","../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/metrics/core/src/metrics.ts","../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/metrics/core/src/symbols.ts"],"sourcesContent":["export * from \"./metrics\";\nexport * from \"./symbols\";\n","import type { Player, PlayerPlugin } from \"@player-ui/player\";\nimport { SyncHook, SyncBailHook } from \"tapable-ts\";\nimport type { BeaconPluginPlugin, BeaconArgs } from \"@player-ui/beacon-plugin\";\nimport { BeaconPlugin } from \"@player-ui/beacon-plugin\";\nimport {\n MetricsCorePluginSymbol,\n MetricsViewBeaconPluginContextSymbol,\n} from \"./symbols\";\n\n// Try to use performance.now() but fall back to Date.now() if you can't\nexport const defaultGetTime =\n typeof performance === \"undefined\"\n ? () => Date.now()\n : () => performance.now();\n\nexport type Timing = {\n /** Time this duration started (ms) */\n startTime: number;\n} & (\n | {\n /** Flag set if this is currently in progress */\n completed: false;\n }\n | {\n /** The stopwatch has stopped */\n completed: true;\n\n /** The time in (ms) that the process ended */\n endTime: number;\n\n /** The elapsed time of this event (ms) */\n duration: number;\n }\n);\n\nexport type NodeMetrics = Timing & {\n /** The type of the flow-state */\n stateType: string;\n\n /** The name of the flow-state */\n stateName: string;\n};\n\nexport type NodeRenderMetrics = NodeMetrics & {\n /** Timing representing the initial render */\n render: Timing;\n\n /** An array of timings representing updates to the view */\n updates: Array<Timing>;\n};\n\nexport interface PlayerFlowMetrics {\n /** All metrics about a running flow */\n flow?: {\n /** The id of the flow these metrics are for */\n id: string;\n\n /** request time */\n requestTime?: number;\n\n /** A timeline of events for each node-state */\n timeline: Array<NodeMetrics | NodeRenderMetrics>;\n\n /** A timing measuring until the first interactive render */\n interactive: Timing;\n } & Timing;\n}\n\nconst callbacks = [\n \"onFlowBegin\",\n \"onFlowEnd\",\n \"onInteractive\",\n \"onNodeStart\",\n \"onNodeEnd\",\n \"onRenderStart\",\n \"onRenderEnd\",\n \"onUpdateStart\",\n \"onUpdateEnd\",\n \"onUpdate\",\n] as const;\n\n/** Context structure for 'viewed' beacons rendering metrics */\nexport interface MetricsViewBeaconPluginContext {\n /** Represents the time taken before the view is first rendered */\n renderTime?: number;\n /** request time */\n requestTime?: number;\n}\n\n/** Simple [BeaconPluginPlugin] that adds renderTime to 'viewed' beacons data */\nexport class MetricsViewBeaconPlugin implements BeaconPluginPlugin {\n static Symbol = MetricsViewBeaconPluginContextSymbol;\n public readonly symbol = MetricsViewBeaconPlugin.Symbol;\n\n private metricsPlugin: MetricsCorePlugin;\n\n private resolvePendingRenderTime: ((renderTime: number) => void) | undefined;\n\n constructor(metricsPlugin: MetricsCorePlugin) {\n this.metricsPlugin = metricsPlugin;\n this.metricsPlugin.hooks.onRenderEnd.tap(\n \"MetricsViewBeaconPlugin\",\n (timing) => {\n if (timing.completed && this.resolvePendingRenderTime) {\n this.resolvePendingRenderTime(timing.duration);\n this.resolvePendingRenderTime = undefined;\n }\n },\n );\n }\n\n apply(beaconPlugin: BeaconPlugin) {\n beaconPlugin.hooks.buildBeacon.intercept({\n context: true,\n call: (context: any, beacon) => {\n if (context && (beacon as BeaconArgs).action === \"viewed\") {\n context[this.symbol] = this.buildContext();\n }\n },\n });\n }\n\n private async buildContext(): Promise<MetricsViewBeaconPluginContext> {\n return {\n renderTime: await this.getRenderTime(),\n requestTime: this.getRequestTime(),\n };\n }\n\n private async getRenderTime(): Promise<number> {\n const { flow } = this.metricsPlugin.getMetrics();\n\n if (flow) {\n const lastItem = flow.timeline[flow.timeline.length - 1];\n\n if (\"render\" in lastItem && lastItem.render.completed) {\n return lastItem.render.duration;\n }\n }\n\n return new Promise((resolve) => {\n this.resolvePendingRenderTime = resolve;\n });\n }\n\n private getRequestTime(): number | undefined {\n const { flow } = this.metricsPlugin.getMetrics();\n\n return flow?.requestTime;\n }\n}\n\nexport interface MetricsWebPluginOptions {\n /** Called when a flow starts */\n onFlowBegin?: (update: PlayerFlowMetrics) => void;\n\n /** Called when a flow ends */\n onFlowEnd?: (update: PlayerFlowMetrics) => void;\n\n /** Called when a flow becomes interactive for the first time */\n onInteractive?: (timing: Timing, update: PlayerFlowMetrics) => void;\n\n /** Called when a new node is started */\n onNodeStart?: (\n nodeMetrics: NodeMetrics | NodeRenderMetrics,\n update: PlayerFlowMetrics,\n ) => void;\n\n /** Called when a node is ended */\n onNodeEnd?: (\n nodeMetrics: NodeMetrics | NodeRenderMetrics,\n update: PlayerFlowMetrics,\n ) => void;\n\n /** Called when rendering for a node begins */\n onRenderStart?: (\n timing: Timing,\n nodeMetrics: NodeRenderMetrics,\n update: PlayerFlowMetrics,\n ) => void;\n\n /** Called when rendering for a node ends */\n onRenderEnd?: (\n timing: Timing,\n nodeMetrics: NodeRenderMetrics,\n update: PlayerFlowMetrics,\n ) => void;\n\n /** Called when an update for a node begins */\n onUpdateStart?: (\n timing: Timing,\n nodeMetrics: NodeRenderMetrics,\n update: PlayerFlowMetrics,\n ) => void;\n\n /** Called when an update for a node ends */\n onUpdateEnd?: (\n timing: Timing,\n nodeMetrics: NodeRenderMetrics,\n update: PlayerFlowMetrics,\n ) => void;\n\n /** Callback to subscribe to updates for any metric */\n onUpdate?: (metrics: PlayerFlowMetrics) => void;\n\n /**\n * A flag to set if you want to track render times for nodes\n * This requires that the UI calls `renderEnd()` when the view is painted.\n */\n trackRenderTime?: boolean;\n\n /**\n * A flag to set if you want to track update times for nodes\n * This requires that the UI calls `renderEnd()` when the view is painted.\n */\n trackUpdateTime?: boolean;\n\n /** A function to get the current time (in ms) */\n getTime?: () => number;\n}\n\n/**\n * A plugin that enables request time metrics\n */\nexport class RequestTimeWebPlugin {\n getRequestTime: () => number | undefined;\n name = \"RequestTimeWebPlugin\";\n\n constructor(getRequestTime: () => number | undefined) {\n this.getRequestTime = getRequestTime;\n }\n\n apply(metricsCorePlugin: MetricsCorePlugin) {\n metricsCorePlugin.hooks.resolveRequestTime.tap(this.name, () => {\n return this.getRequestTime();\n });\n }\n}\n\n/**\n * A plugin that enables gathering of render metrics\n */\nexport class MetricsCorePlugin implements PlayerPlugin {\n name = \"metrics\";\n\n static Symbol = MetricsCorePluginSymbol;\n public readonly symbol = MetricsCorePluginSymbol;\n\n protected trackRender: boolean;\n protected trackUpdate: boolean;\n protected getTime: () => number;\n\n public readonly hooks = {\n resolveRequestTime: new SyncBailHook<[], number>(),\n\n onFlowBegin: new SyncHook<[PlayerFlowMetrics]>(),\n onFlowEnd: new SyncHook<[PlayerFlowMetrics]>(),\n\n onInteractive: new SyncHook<[Timing, PlayerFlowMetrics]>(),\n\n onNodeStart: new SyncHook<[NodeMetrics | NodeRenderMetrics]>(),\n onNodeEnd: new SyncHook<[NodeMetrics | NodeRenderMetrics]>(),\n\n onRenderStart: new SyncHook<\n [Timing, NodeRenderMetrics, PlayerFlowMetrics]\n >(),\n onRenderEnd: new SyncHook<[Timing, NodeRenderMetrics, PlayerFlowMetrics]>(),\n\n onUpdateStart: new SyncHook<\n [Timing, NodeRenderMetrics, PlayerFlowMetrics]\n >(),\n onUpdateEnd: new SyncHook<[Timing, NodeRenderMetrics, PlayerFlowMetrics]>(),\n\n onUpdate: new SyncHook<[PlayerFlowMetrics]>(),\n };\n\n private metrics: PlayerFlowMetrics = {};\n\n constructor(options?: MetricsWebPluginOptions) {\n this.trackRender = options?.trackRenderTime ?? false;\n this.trackUpdate = options?.trackUpdateTime ?? false;\n this.getTime = options?.getTime ?? defaultGetTime;\n\n /** fn to call the update hook */\n const callOnUpdate = () => {\n this.hooks.onUpdate.call(this.metrics);\n };\n\n this.hooks.onFlowBegin.tap(this.name, callOnUpdate);\n this.hooks.onFlowEnd.tap(this.name, callOnUpdate);\n this.hooks.onInteractive.tap(this.name, callOnUpdate);\n this.hooks.onNodeStart.tap(this.name, callOnUpdate);\n this.hooks.onNodeEnd.tap(this.name, callOnUpdate);\n\n this.hooks.onRenderStart.tap(this.name, callOnUpdate);\n this.hooks.onRenderEnd.tap(this.name, callOnUpdate);\n\n this.hooks.onUpdateStart.tap(this.name, callOnUpdate);\n this.hooks.onUpdateEnd.tap(this.name, callOnUpdate);\n\n callbacks.forEach((hookName) => {\n if (options?.[hookName] !== undefined) {\n (this.hooks[hookName] as any).tap(\"options\", options?.[hookName]);\n }\n });\n }\n\n /**\n * Fetch the metrics of the current flow\n */\n public getMetrics(): PlayerFlowMetrics {\n return this.metrics;\n }\n\n /** Called when the UI layer wishes to start a timer for rendering */\n private renderStart(): void {\n // Grab the last update\n const timeline = this.metrics.flow?.timeline;\n\n if (!timeline || timeline.length === 0) {\n return;\n }\n\n const lastItem = timeline[timeline.length - 1];\n\n if (\"updates\" in lastItem) {\n // Get the last update, make sure it's completed\n if (lastItem.updates.length > 0) {\n const lastUpdate = lastItem.updates[lastItem.updates.length - 1];\n\n if (lastUpdate.completed === false) {\n // Starting a new render before the last one was finished.\n // Just ignore it and include as part of 1 render time\n return;\n }\n }\n\n if (!lastItem.render.completed) {\n // Starting a new render before the last one was finished.\n // Just ignore it and include as part of 1 render time\n return;\n }\n\n const update: Timing = {\n completed: false,\n startTime: defaultGetTime(),\n };\n\n lastItem.updates.push(update);\n\n this.hooks.onUpdateStart.call(update, lastItem, this.metrics);\n } else {\n const renderInfo = {\n ...lastItem,\n render: {\n completed: false,\n startTime: defaultGetTime(),\n },\n updates: [],\n } as NodeRenderMetrics;\n\n timeline[timeline.length - 1] = renderInfo;\n\n this.hooks.onRenderStart.call(\n renderInfo.render,\n renderInfo,\n this.metrics,\n );\n }\n }\n\n /** Called when the UI layer wants to end the rendering timer */\n public renderEnd(): void {\n if (!this.trackRender) {\n throw new Error(\n \"Must start the metrics-plugin with render tracking enabled\",\n );\n }\n\n const { flow } = this.metrics;\n\n if (!flow) {\n return;\n }\n\n const { timeline, interactive } = flow;\n\n if (!timeline || !interactive || timeline.length === 0) {\n return;\n }\n\n const lastItem = timeline[timeline.length - 1];\n\n if (!(\"render\" in lastItem)) {\n return;\n }\n\n // Check if this is an update or render\n const endTime = defaultGetTime();\n\n if (lastItem.render.completed) {\n // This is the end of an existing update\n\n if (lastItem.updates.length === 0) {\n // throw new Error(\"Trying to end an update that's not in progress\");\n return;\n }\n\n const lastUpdate = lastItem.updates[lastItem.updates.length - 1];\n\n if (lastUpdate.completed === true) {\n // throw new Error(\"Trying to end an update that's not in progress\");\n return;\n }\n\n const update = {\n ...lastUpdate,\n completed: true,\n endTime,\n duration: endTime - lastUpdate.startTime,\n };\n\n lastItem.updates[lastItem.updates.length - 1] = update;\n this.hooks.onUpdateEnd.call(update, lastItem, this.metrics);\n } else {\n lastItem.render = {\n ...lastItem.render,\n completed: true,\n endTime,\n duration: endTime - lastItem.startTime,\n };\n this.hooks.onRenderEnd.call(lastItem.render, lastItem, this.metrics);\n\n if (!interactive.completed) {\n flow.interactive = {\n ...interactive,\n completed: true,\n duration: endTime - interactive.startTime,\n endTime,\n };\n\n this.hooks.onInteractive.call(flow.interactive, this.metrics);\n }\n }\n }\n\n apply(player: Player): void {\n player.hooks.onStart.tap(this.name, (flow) => {\n const requestTime = this.hooks.resolveRequestTime.call();\n const startTime = defaultGetTime();\n this.metrics = {\n flow: {\n id: flow.id,\n requestTime: requestTime ?? undefined,\n timeline: [],\n startTime,\n completed: false,\n interactive: {\n completed: false,\n startTime,\n },\n },\n };\n\n this.hooks.onFlowBegin.call(this.metrics);\n });\n\n player.hooks.state.tap(this.name, (state) => {\n if (state.status === \"completed\" || state.status === \"error\") {\n const endTime = defaultGetTime();\n const { flow } = this.metrics;\n\n if (flow === undefined || flow?.completed === true) {\n return;\n }\n\n this.metrics = {\n flow: {\n ...flow,\n completed: true,\n endTime,\n duration: endTime - flow.startTime,\n },\n };\n\n // get the last update\n\n const lastUpdate = flow.timeline[flow.timeline.length - 1];\n\n if (lastUpdate && !lastUpdate.completed) {\n (this.metrics.flow as any).timeline[flow.timeline.length - 1] = {\n ...lastUpdate,\n completed: true,\n endTime,\n duration: endTime - lastUpdate.startTime,\n };\n }\n\n this.hooks.onFlowEnd.call(this.metrics);\n }\n });\n\n player.hooks.flowController.tap(this.name, (fc) => {\n fc.hooks.flow.tap(this.name, (f) => {\n f.hooks.transition.tap(this.name, (from, to) => {\n const time = defaultGetTime();\n const { flow } = this.metrics;\n\n if (!flow) {\n return;\n }\n\n const { timeline } = flow;\n\n // End the last state, and start the next one\n\n if (timeline.length > 0) {\n const prev = timeline[timeline.length - 1];\n\n if (prev.completed) {\n throw new Error(\"Completing a state that's already done.\");\n }\n\n timeline[timeline.length - 1] = {\n ...prev,\n completed: true,\n endTime: time,\n duration: time - prev.startTime,\n };\n\n this.hooks.onNodeEnd.call(timeline[timeline.length - 1]);\n }\n\n const nodeMetrics = {\n completed: false,\n startTime: time,\n stateName: to.name,\n stateType: to.value.state_type,\n } as const;\n\n timeline.push(nodeMetrics);\n this.hooks.onNodeStart.call(nodeMetrics);\n });\n });\n });\n\n if (this.trackRender) {\n player.hooks.view.tap(this.name, (v) => {\n if (this.trackUpdate) {\n v.hooks.onUpdate.tap(this.name, () => {\n this.renderStart();\n });\n } else {\n this.renderStart();\n }\n });\n\n player.applyTo<BeaconPlugin>(BeaconPlugin.Symbol, (beaconPlugin) =>\n new MetricsViewBeaconPlugin(this).apply(beaconPlugin),\n );\n }\n }\n}\n\nexport default MetricsCorePlugin;\n","export const MetricsCorePluginSymbol = Symbol.for(\"MetricsCorePlugin\");\nexport const MetricsViewBeaconPluginContextSymbol = Symbol.for(\n \"MetricsViewBeaconPluginContext\",\n);\n"],"mappings":"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","names":[]}