@atlaskit/insm 0.1.2 → 0.1.3
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/CHANGELOG.md +6 -0
- package/README.md +14 -0
- package/dist/cjs/index.js +5 -2
- package/dist/cjs/insm-session.js +63 -6
- package/dist/cjs/insm.js +27 -1
- package/dist/cjs/session-measurers/LongAnimationFrameMeasurer.js +122 -0
- package/dist/es2019/index.js +5 -2
- package/dist/es2019/insm-session.js +58 -1
- package/dist/es2019/insm.js +24 -1
- package/dist/es2019/session-measurers/LongAnimationFrameMeasurer.js +101 -0
- package/dist/esm/index.js +5 -2
- package/dist/esm/insm-session.js +65 -6
- package/dist/esm/insm.js +27 -1
- package/dist/esm/session-measurers/LongAnimationFrameMeasurer.js +118 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/insm-session.d.ts +5 -2
- package/dist/types/insm.d.ts +7 -0
- package/dist/types/session-measurers/LongAnimationFrameMeasurer.d.ts +61 -0
- package/dist/types-ts4.5/index.d.ts +1 -1
- package/dist/types-ts4.5/insm-session.d.ts +5 -2
- package/dist/types-ts4.5/insm.d.ts +7 -0
- package/dist/types-ts4.5/session-measurers/LongAnimationFrameMeasurer.d.ts +61 -0
- package/package.json +5 -4
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -169,6 +169,20 @@ insm.start(experienceKey, {
|
|
|
169
169
|
Note: calling this will end any existing experience (unless the experience key and properties
|
|
170
170
|
match - in which case no session change will occur).
|
|
171
171
|
|
|
172
|
+
#### Updating a page session experienceKey after it's started
|
|
173
|
+
|
|
174
|
+
In some scenarios you may need to update the running sessions experience key after it has started,
|
|
175
|
+
in these cases you can use `overrideExperienceKey`.
|
|
176
|
+
|
|
177
|
+
If there is a running experience, it will update the running experiences name.
|
|
178
|
+
|
|
179
|
+
If there is no running experience (ie. if the original experienceKey had not been whitelisted), it
|
|
180
|
+
will start a new experience using the last started experienceProperties.
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
insm.overrideExperienceKey('new-key');
|
|
184
|
+
```
|
|
185
|
+
|
|
172
186
|
#### Naming guidance
|
|
173
187
|
|
|
174
188
|
Choose an `experienceKey` that reflects the product and content type you want to analyze.
|
package/dist/cjs/index.js
CHANGED
|
@@ -16,8 +16,6 @@ function init(options) {
|
|
|
16
16
|
}
|
|
17
17
|
function insmInitialised() {
|
|
18
18
|
if (!initialisedInsm) {
|
|
19
|
-
// eslint-disable-next-line no-console
|
|
20
|
-
console.error('INSM used when not initialised');
|
|
21
19
|
return false;
|
|
22
20
|
}
|
|
23
21
|
return true;
|
|
@@ -42,6 +40,11 @@ var insm = exports.insm = {
|
|
|
42
40
|
initialisedInsm.start(experienceKey, experienceProperties);
|
|
43
41
|
}
|
|
44
42
|
},
|
|
43
|
+
overrideExperienceKey: function overrideExperienceKey(experienceKey) {
|
|
44
|
+
if (insmInitialised()) {
|
|
45
|
+
initialisedInsm.overrideExperienceKey(experienceKey);
|
|
46
|
+
}
|
|
47
|
+
},
|
|
45
48
|
stopEarly: function stopEarly(reasonKey, description) {
|
|
46
49
|
if (insmInitialised()) {
|
|
47
50
|
initialisedInsm.stopEarly(reasonKey, description);
|
package/dist/cjs/insm-session.js
CHANGED
|
@@ -8,7 +8,10 @@ exports.INSMSession = void 0;
|
|
|
8
8
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
9
9
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
10
10
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
|
+
var _bowserUltralight = _interopRequireDefault(require("bowser-ultralight"));
|
|
12
|
+
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
11
13
|
var _insmPeriod = require("./insm-period");
|
|
14
|
+
var _LongAnimationFrameMeasurer = require("./session-measurers/LongAnimationFrameMeasurer");
|
|
12
15
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
13
16
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
14
17
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
@@ -30,16 +33,27 @@ var INSMSession = exports.INSMSession = /*#__PURE__*/function () {
|
|
|
30
33
|
this.experienceProperties = experienceProperties;
|
|
31
34
|
this.insm = insm;
|
|
32
35
|
this.periodTracking = new _insmPeriod.PeriodTracking(this);
|
|
36
|
+
this.longAnimationFrameMeasurer = new _LongAnimationFrameMeasurer.LongAnimationFrameMeasurer({
|
|
37
|
+
initial: this.experienceProperties.initial,
|
|
38
|
+
limit: 3,
|
|
39
|
+
insmSession: this,
|
|
40
|
+
reportingThreshold: 500
|
|
41
|
+
});
|
|
33
42
|
|
|
34
43
|
/**
|
|
35
44
|
* Note: Events are not reliably fired from mobile browsers (ie. when a browser is closed when not in use)
|
|
36
45
|
*/
|
|
37
46
|
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Adds a feature to the currently running session
|
|
41
|
-
*/
|
|
42
47
|
return (0, _createClass2.default)(INSMSession, [{
|
|
48
|
+
key: "updateExperienceKey",
|
|
49
|
+
value: function updateExperienceKey(experienceKey) {
|
|
50
|
+
this.experienceKey = experienceKey;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Adds a feature to the currently running session
|
|
55
|
+
*/
|
|
56
|
+
}, {
|
|
43
57
|
key: "startFeature",
|
|
44
58
|
value: function startFeature(featureName) {
|
|
45
59
|
var _this$periodTracking;
|
|
@@ -172,13 +186,56 @@ var INSMSession = exports.INSMSession = /*#__PURE__*/function () {
|
|
|
172
186
|
duration: duration
|
|
173
187
|
},
|
|
174
188
|
periods: periodResults,
|
|
175
|
-
endDetails: endDetails
|
|
189
|
+
endDetails: endDetails,
|
|
190
|
+
longAnimationFrames: this.longAnimationFrameMeasurer.current
|
|
176
191
|
}),
|
|
192
|
+
deviceDetails: (0, _expValEquals.expValEquals)('cc_editor_interactivity_monitoring', 'isEnabled', true) ? getDeviceDetails() : undefined,
|
|
177
193
|
highPriority: true,
|
|
178
194
|
tags: ['editor'],
|
|
179
195
|
source: 'unknown'
|
|
180
196
|
};
|
|
181
197
|
(_this$insm$analyticsW = this.insm.analyticsWebClient) === null || _this$insm$analyticsW === void 0 || _this$insm$analyticsW.sendOperationalEvent(operationalEvent);
|
|
198
|
+
this.longAnimationFrameMeasurer.cleanup();
|
|
182
199
|
}
|
|
183
200
|
}]);
|
|
184
|
-
}();
|
|
201
|
+
}(); // Functionality vendored from UFO
|
|
202
|
+
function getDeviceDetails() {
|
|
203
|
+
var _navigator$connection, _navigator$connection2, _navigator$connection3;
|
|
204
|
+
var telemetry = {};
|
|
205
|
+
|
|
206
|
+
// /platform/packages/data/ufo-internal/src/core/publisher/plugins/browser.ts
|
|
207
|
+
if (_bowserUltralight.default.getParser) {
|
|
208
|
+
var _ref;
|
|
209
|
+
var browser = _bowserUltralight.default.getParser(((_ref = typeof window !== 'undefined' && !!window ? window : undefined) === null || _ref === void 0 || (_ref = _ref.navigator) === null || _ref === void 0 ? void 0 : _ref.userAgent) || '');
|
|
210
|
+
Object.assign(telemetry, {
|
|
211
|
+
'event:browser:name': browser.getBrowserName(),
|
|
212
|
+
'event:browser:version': browser.getBrowserVersion()
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// /platform/packages/data/ufo-internal/src/core/publisher/plugins/cpus.ts
|
|
217
|
+
Object.assign(telemetry, {
|
|
218
|
+
'event:cpus': navigator.hardwareConcurrency
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// /platform/packages/data/ufo-internal/src/core/publisher/plugins/memory.ts
|
|
222
|
+
// @ts-ignore: deviceMemory is exposed in some browsers
|
|
223
|
+
Object.assign(telemetry, {
|
|
224
|
+
'event:memory': navigator.deviceMemory
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// /platform/packages/data/ufo-internal/src/core/publisher/plugins/network.ts
|
|
228
|
+
Object.assign(telemetry, {
|
|
229
|
+
// Network
|
|
230
|
+
// @ts-ignore: connection is available in some browsers
|
|
231
|
+
// eslint-disable-next-line compat/compat
|
|
232
|
+
'event:network:effectiveType': (_navigator$connection = navigator.connection) === null || _navigator$connection === void 0 ? void 0 : _navigator$connection.effectiveType,
|
|
233
|
+
// @ts-ignore: connection is available in some browsers
|
|
234
|
+
// eslint-disable-next-line compat/compat
|
|
235
|
+
'event:network:rtt': (_navigator$connection2 = navigator.connection) === null || _navigator$connection2 === void 0 ? void 0 : _navigator$connection2.rtt,
|
|
236
|
+
// @ts-ignore: connection is available in some browsers
|
|
237
|
+
// eslint-disable-next-line compat/compat
|
|
238
|
+
'event:network:downlink': (_navigator$connection3 = navigator.connection) === null || _navigator$connection3 === void 0 ? void 0 : _navigator$connection3.downlink
|
|
239
|
+
});
|
|
240
|
+
return telemetry;
|
|
241
|
+
}
|
package/dist/cjs/insm.js
CHANGED
|
@@ -57,10 +57,11 @@ var INSM = exports.INSM = /*#__PURE__*/function () {
|
|
|
57
57
|
return (0, _createClass2.default)(INSM, [{
|
|
58
58
|
key: "startHeavyTask",
|
|
59
59
|
value: function startHeavyTask(heavyTaskName) {
|
|
60
|
-
var _this$runningSession2, _this$runningSession3;
|
|
60
|
+
var _this$runningSession2, _this$runningSession3, _this$session;
|
|
61
61
|
this.runningHeavyTasks.add(heavyTaskName);
|
|
62
62
|
(_this$runningSession2 = this.runningSession) === null || _this$runningSession2 === void 0 || (_this$runningSession2 = _this$runningSession2.periodTracking) === null || _this$runningSession2 === void 0 || _this$runningSession2.startHeavyTask(heavyTaskName);
|
|
63
63
|
(_this$runningSession3 = this.runningSession) === null || _this$runningSession3 === void 0 || _this$runningSession3.periodTracking.pause(heavyTaskName);
|
|
64
|
+
(_this$session = this.session) === null || _this$session === void 0 || _this$session.longAnimationFrameMeasurer.pause();
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
/**
|
|
@@ -72,6 +73,10 @@ var INSM = exports.INSM = /*#__PURE__*/function () {
|
|
|
72
73
|
var _this$runningSession4;
|
|
73
74
|
this.runningHeavyTasks.delete(heavyTaskName);
|
|
74
75
|
(_this$runningSession4 = this.runningSession) === null || _this$runningSession4 === void 0 || _this$runningSession4.periodTracking.resume(heavyTaskName);
|
|
76
|
+
if (this.runningHeavyTasks.size === 0) {
|
|
77
|
+
var _this$session2;
|
|
78
|
+
(_this$session2 = this.session) === null || _this$session2 === void 0 || _this$session2.longAnimationFrameMeasurer.resume();
|
|
79
|
+
}
|
|
75
80
|
}
|
|
76
81
|
|
|
77
82
|
/**
|
|
@@ -100,10 +105,31 @@ var INSM = exports.INSM = /*#__PURE__*/function () {
|
|
|
100
105
|
contentId: experienceProperties.contentId
|
|
101
106
|
});
|
|
102
107
|
}
|
|
108
|
+
this.lastStartedExperienceProperties = experienceProperties;
|
|
103
109
|
if ((_this$options$experie = this.options.experiences[experienceKey]) !== null && _this$options$experie !== void 0 && _this$options$experie.enabled) {
|
|
104
110
|
this.runningSession = new _insmSession.INSMSession(experienceKey, experienceProperties, this);
|
|
105
111
|
}
|
|
106
112
|
}
|
|
113
|
+
}, {
|
|
114
|
+
key: "overrideExperienceKey",
|
|
115
|
+
value:
|
|
116
|
+
/**
|
|
117
|
+
* Call this to update the name of the running session after it's started
|
|
118
|
+
* In the case it's been started with an unregistered name, and there is not running
|
|
119
|
+
* session. This will also trigger the session being started.
|
|
120
|
+
*/
|
|
121
|
+
function overrideExperienceKey(experienceKey) {
|
|
122
|
+
if (this.runningSession !== undefined) {
|
|
123
|
+
// If there is a running session - we update its name
|
|
124
|
+
this.runningSession.updateExperienceKey(experienceKey);
|
|
125
|
+
} else {
|
|
126
|
+
var _this$options$experie2;
|
|
127
|
+
// otherwise - we assume the last session was not registered, and start it with the new name
|
|
128
|
+
if ((_this$options$experie2 = this.options.experiences[experienceKey]) !== null && _this$options$experie2 !== void 0 && _this$options$experie2.enabled && this.lastStartedExperienceProperties) {
|
|
129
|
+
this.runningSession = new _insmSession.INSMSession(experienceKey, this.lastStartedExperienceProperties, this);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
107
133
|
|
|
108
134
|
/**
|
|
109
135
|
* This prematurely halts any running experience measurement. It's expected to be used in
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.LongAnimationFrameMeasurer = void 0;
|
|
8
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
9
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
10
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
|
+
var LongAnimationFrameMeasurer = exports.LongAnimationFrameMeasurer = /*#__PURE__*/function () {
|
|
12
|
+
function LongAnimationFrameMeasurer(options) {
|
|
13
|
+
var _this = this;
|
|
14
|
+
(0, _classCallCheck2.default)(this, LongAnimationFrameMeasurer);
|
|
15
|
+
(0, _defineProperty2.default)(this, "longestAnimationFrames", []);
|
|
16
|
+
(0, _defineProperty2.default)(this, "minimumIndex", -1);
|
|
17
|
+
(0, _defineProperty2.default)(this, "minimumDuration", Infinity);
|
|
18
|
+
this.options = options;
|
|
19
|
+
this.paused = options.insmSession.insm.runningHeavyTasks.size !== 0;
|
|
20
|
+
if (PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')) {
|
|
21
|
+
this.observer = new PerformanceObserver(function (list) {
|
|
22
|
+
if (!_this.paused) {
|
|
23
|
+
// only handle batches when tracking is not paused
|
|
24
|
+
_this.handleBatch(list.getEntries());
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
this.observer.observe({
|
|
28
|
+
type: 'long-animation-frame',
|
|
29
|
+
buffered: options.initial
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return (0, _createClass2.default)(LongAnimationFrameMeasurer, [{
|
|
34
|
+
key: "handleBatch",
|
|
35
|
+
value: function handleBatch(batch) {
|
|
36
|
+
var len = this.longestAnimationFrames.length;
|
|
37
|
+
for (var batchIndex = 0; batchIndex < batch.length; batchIndex++) {
|
|
38
|
+
if (batch[batchIndex].duration < this.options.reportingThreshold) {
|
|
39
|
+
// If the long frame entry had a duration less than the reporting
|
|
40
|
+
// threshold it's not eligible for tracking
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
var longAnimationFrameEntry = Object.assign(batch[batchIndex], {
|
|
44
|
+
runningFeatures: Array.from(this.options.insmSession.runningFeatures)
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Not yet at capacity: append and update min tracking incrementally
|
|
48
|
+
if (len < this.options.limit) {
|
|
49
|
+
this.longestAnimationFrames[len] = longAnimationFrameEntry;
|
|
50
|
+
if (len === 0 || longAnimationFrameEntry.duration < this.minimumDuration) {
|
|
51
|
+
this.minimumDuration = longAnimationFrameEntry.duration;
|
|
52
|
+
this.minimumIndex = len;
|
|
53
|
+
}
|
|
54
|
+
len++;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// At capacity: only do work if we beat the current min
|
|
59
|
+
if (longAnimationFrameEntry.duration <= this.minimumDuration) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Replace the current min
|
|
64
|
+
this.longestAnimationFrames[this.minimumIndex] = longAnimationFrameEntry;
|
|
65
|
+
var _possiblyNewMinimumIndex = 0;
|
|
66
|
+
var _possibleNewMinimumDuration = this.longestAnimationFrames[0].duration;
|
|
67
|
+
for (var i = 1; i < this.options.limit; i++) {
|
|
68
|
+
if (this.longestAnimationFrames[i].duration < _possibleNewMinimumDuration) {
|
|
69
|
+
_possiblyNewMinimumIndex = i;
|
|
70
|
+
_possibleNewMinimumDuration = this.longestAnimationFrames[i].duration;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Update the min tracking
|
|
75
|
+
this.minimumIndex = _possiblyNewMinimumIndex;
|
|
76
|
+
this.minimumDuration = _possibleNewMinimumDuration;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Pauses tracking
|
|
82
|
+
*/
|
|
83
|
+
}, {
|
|
84
|
+
key: "pause",
|
|
85
|
+
value: function pause() {
|
|
86
|
+
this.paused = true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Resumes tracking
|
|
91
|
+
*/
|
|
92
|
+
}, {
|
|
93
|
+
key: "resume",
|
|
94
|
+
value: function resume() {
|
|
95
|
+
this.paused = false;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Returns the current tracked longest animation frames sorted by duration
|
|
100
|
+
*/
|
|
101
|
+
}, {
|
|
102
|
+
key: "current",
|
|
103
|
+
get: function get() {
|
|
104
|
+
var copy = this.longestAnimationFrames.slice();
|
|
105
|
+
copy.sort(function (a, b) {
|
|
106
|
+
return b.duration - a.duration;
|
|
107
|
+
});
|
|
108
|
+
return copy;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Cleans up the performance tracking (tracking cannot be resumed following this).
|
|
113
|
+
*/
|
|
114
|
+
}, {
|
|
115
|
+
key: "cleanup",
|
|
116
|
+
value: function cleanup() {
|
|
117
|
+
var _this$observer;
|
|
118
|
+
(_this$observer = this.observer) === null || _this$observer === void 0 || _this$observer.disconnect();
|
|
119
|
+
}
|
|
120
|
+
}]);
|
|
121
|
+
}(); // Based on https://github.com/GoogleChrome/web-vitals/blob/1b872cf5f2159e8ace0e98d55d8eb54fb09adfbe/src/types.ts#L129
|
|
122
|
+
// Based on https://github.com/GoogleChrome/web-vitals/blob/1b872cf5f2159e8ace0e98d55d8eb54fb09adfbe/src/types.ts#L129
|
package/dist/es2019/index.js
CHANGED
|
@@ -9,8 +9,6 @@ export function init(options) {
|
|
|
9
9
|
}
|
|
10
10
|
function insmInitialised() {
|
|
11
11
|
if (!initialisedInsm) {
|
|
12
|
-
// eslint-disable-next-line no-console
|
|
13
|
-
console.error('INSM used when not initialised');
|
|
14
12
|
return false;
|
|
15
13
|
}
|
|
16
14
|
return true;
|
|
@@ -35,6 +33,11 @@ export const insm = {
|
|
|
35
33
|
initialisedInsm.start(experienceKey, experienceProperties);
|
|
36
34
|
}
|
|
37
35
|
},
|
|
36
|
+
overrideExperienceKey(experienceKey) {
|
|
37
|
+
if (insmInitialised()) {
|
|
38
|
+
initialisedInsm.overrideExperienceKey(experienceKey);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
38
41
|
stopEarly(reasonKey, description) {
|
|
39
42
|
if (insmInitialised()) {
|
|
40
43
|
initialisedInsm.stopEarly(reasonKey, description);
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
import Bowser from 'bowser-ultralight';
|
|
3
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
2
4
|
import { PeriodTracking } from './insm-period';
|
|
5
|
+
import { LongAnimationFrameMeasurer } from './session-measurers/LongAnimationFrameMeasurer';
|
|
3
6
|
|
|
4
7
|
/**
|
|
5
8
|
* Only intended for internal use.
|
|
@@ -16,11 +19,20 @@ export class INSMSession {
|
|
|
16
19
|
this.experienceProperties = experienceProperties;
|
|
17
20
|
this.insm = insm;
|
|
18
21
|
this.periodTracking = new PeriodTracking(this);
|
|
22
|
+
this.longAnimationFrameMeasurer = new LongAnimationFrameMeasurer({
|
|
23
|
+
initial: this.experienceProperties.initial,
|
|
24
|
+
limit: 3,
|
|
25
|
+
insmSession: this,
|
|
26
|
+
reportingThreshold: 500
|
|
27
|
+
});
|
|
19
28
|
|
|
20
29
|
/**
|
|
21
30
|
* Note: Events are not reliably fired from mobile browsers (ie. when a browser is closed when not in use)
|
|
22
31
|
*/
|
|
23
32
|
}
|
|
33
|
+
updateExperienceKey(experienceKey) {
|
|
34
|
+
this.experienceKey = experienceKey;
|
|
35
|
+
}
|
|
24
36
|
|
|
25
37
|
/**
|
|
26
38
|
* Adds a feature to the currently running session
|
|
@@ -139,12 +151,57 @@ export class INSMSession {
|
|
|
139
151
|
duration
|
|
140
152
|
},
|
|
141
153
|
periods: periodResults,
|
|
142
|
-
endDetails: endDetails
|
|
154
|
+
endDetails: endDetails,
|
|
155
|
+
longAnimationFrames: this.longAnimationFrameMeasurer.current
|
|
143
156
|
},
|
|
157
|
+
deviceDetails: expValEquals('cc_editor_interactivity_monitoring', 'isEnabled', true) ? getDeviceDetails() : undefined,
|
|
144
158
|
highPriority: true,
|
|
145
159
|
tags: ['editor'],
|
|
146
160
|
source: 'unknown'
|
|
147
161
|
};
|
|
148
162
|
(_this$insm$analyticsW = this.insm.analyticsWebClient) === null || _this$insm$analyticsW === void 0 ? void 0 : _this$insm$analyticsW.sendOperationalEvent(operationalEvent);
|
|
163
|
+
this.longAnimationFrameMeasurer.cleanup();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Functionality vendored from UFO
|
|
168
|
+
function getDeviceDetails() {
|
|
169
|
+
var _navigator$connection, _navigator$connection2, _navigator$connection3;
|
|
170
|
+
const telemetry = {};
|
|
171
|
+
|
|
172
|
+
// /platform/packages/data/ufo-internal/src/core/publisher/plugins/browser.ts
|
|
173
|
+
if (Bowser.getParser) {
|
|
174
|
+
var _ref, _ref$navigator;
|
|
175
|
+
const browser = Bowser.getParser(((_ref = typeof window !== 'undefined' && !!window ? window : undefined) === null || _ref === void 0 ? void 0 : (_ref$navigator = _ref.navigator) === null || _ref$navigator === void 0 ? void 0 : _ref$navigator.userAgent) || '');
|
|
176
|
+
Object.assign(telemetry, {
|
|
177
|
+
'event:browser:name': browser.getBrowserName(),
|
|
178
|
+
'event:browser:version': browser.getBrowserVersion()
|
|
179
|
+
});
|
|
149
180
|
}
|
|
181
|
+
|
|
182
|
+
// /platform/packages/data/ufo-internal/src/core/publisher/plugins/cpus.ts
|
|
183
|
+
Object.assign(telemetry, {
|
|
184
|
+
'event:cpus': navigator.hardwareConcurrency
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// /platform/packages/data/ufo-internal/src/core/publisher/plugins/memory.ts
|
|
188
|
+
// @ts-ignore: deviceMemory is exposed in some browsers
|
|
189
|
+
Object.assign(telemetry, {
|
|
190
|
+
'event:memory': navigator.deviceMemory
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// /platform/packages/data/ufo-internal/src/core/publisher/plugins/network.ts
|
|
194
|
+
Object.assign(telemetry, {
|
|
195
|
+
// Network
|
|
196
|
+
// @ts-ignore: connection is available in some browsers
|
|
197
|
+
// eslint-disable-next-line compat/compat
|
|
198
|
+
'event:network:effectiveType': (_navigator$connection = navigator.connection) === null || _navigator$connection === void 0 ? void 0 : _navigator$connection.effectiveType,
|
|
199
|
+
// @ts-ignore: connection is available in some browsers
|
|
200
|
+
// eslint-disable-next-line compat/compat
|
|
201
|
+
'event:network:rtt': (_navigator$connection2 = navigator.connection) === null || _navigator$connection2 === void 0 ? void 0 : _navigator$connection2.rtt,
|
|
202
|
+
// @ts-ignore: connection is available in some browsers
|
|
203
|
+
// eslint-disable-next-line compat/compat
|
|
204
|
+
'event:network:downlink': (_navigator$connection3 = navigator.connection) === null || _navigator$connection3 === void 0 ? void 0 : _navigator$connection3.downlink
|
|
205
|
+
});
|
|
206
|
+
return telemetry;
|
|
150
207
|
}
|
package/dist/es2019/insm.js
CHANGED
|
@@ -42,10 +42,11 @@ export class INSM {
|
|
|
42
42
|
* This also pauses measurement.
|
|
43
43
|
*/
|
|
44
44
|
startHeavyTask(heavyTaskName) {
|
|
45
|
-
var _this$runningSession2, _this$runningSession3, _this$runningSession4;
|
|
45
|
+
var _this$runningSession2, _this$runningSession3, _this$runningSession4, _this$session;
|
|
46
46
|
this.runningHeavyTasks.add(heavyTaskName);
|
|
47
47
|
(_this$runningSession2 = this.runningSession) === null || _this$runningSession2 === void 0 ? void 0 : (_this$runningSession3 = _this$runningSession2.periodTracking) === null || _this$runningSession3 === void 0 ? void 0 : _this$runningSession3.startHeavyTask(heavyTaskName);
|
|
48
48
|
(_this$runningSession4 = this.runningSession) === null || _this$runningSession4 === void 0 ? void 0 : _this$runningSession4.periodTracking.pause(heavyTaskName);
|
|
49
|
+
(_this$session = this.session) === null || _this$session === void 0 ? void 0 : _this$session.longAnimationFrameMeasurer.pause();
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
/**
|
|
@@ -55,6 +56,10 @@ export class INSM {
|
|
|
55
56
|
var _this$runningSession5;
|
|
56
57
|
this.runningHeavyTasks.delete(heavyTaskName);
|
|
57
58
|
(_this$runningSession5 = this.runningSession) === null || _this$runningSession5 === void 0 ? void 0 : _this$runningSession5.periodTracking.resume(heavyTaskName);
|
|
59
|
+
if (this.runningHeavyTasks.size === 0) {
|
|
60
|
+
var _this$session2;
|
|
61
|
+
(_this$session2 = this.session) === null || _this$session2 === void 0 ? void 0 : _this$session2.longAnimationFrameMeasurer.resume();
|
|
62
|
+
}
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
/**
|
|
@@ -81,10 +86,28 @@ export class INSM {
|
|
|
81
86
|
contentId: experienceProperties.contentId
|
|
82
87
|
});
|
|
83
88
|
}
|
|
89
|
+
this.lastStartedExperienceProperties = experienceProperties;
|
|
84
90
|
if ((_this$options$experie = this.options.experiences[experienceKey]) !== null && _this$options$experie !== void 0 && _this$options$experie.enabled) {
|
|
85
91
|
this.runningSession = new INSMSession(experienceKey, experienceProperties, this);
|
|
86
92
|
}
|
|
87
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Call this to update the name of the running session after it's started
|
|
96
|
+
* In the case it's been started with an unregistered name, and there is not running
|
|
97
|
+
* session. This will also trigger the session being started.
|
|
98
|
+
*/
|
|
99
|
+
overrideExperienceKey(experienceKey) {
|
|
100
|
+
if (this.runningSession !== undefined) {
|
|
101
|
+
// If there is a running session - we update its name
|
|
102
|
+
this.runningSession.updateExperienceKey(experienceKey);
|
|
103
|
+
} else {
|
|
104
|
+
var _this$options$experie2;
|
|
105
|
+
// otherwise - we assume the last session was not registered, and start it with the new name
|
|
106
|
+
if ((_this$options$experie2 = this.options.experiences[experienceKey]) !== null && _this$options$experie2 !== void 0 && _this$options$experie2.enabled && this.lastStartedExperienceProperties) {
|
|
107
|
+
this.runningSession = new INSMSession(experienceKey, this.lastStartedExperienceProperties, this);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
88
111
|
|
|
89
112
|
/**
|
|
90
113
|
* This prematurely halts any running experience measurement. It's expected to be used in
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
export class LongAnimationFrameMeasurer {
|
|
3
|
+
constructor(options) {
|
|
4
|
+
_defineProperty(this, "longestAnimationFrames", []);
|
|
5
|
+
_defineProperty(this, "minimumIndex", -1);
|
|
6
|
+
_defineProperty(this, "minimumDuration", Infinity);
|
|
7
|
+
this.options = options;
|
|
8
|
+
this.paused = options.insmSession.insm.runningHeavyTasks.size !== 0;
|
|
9
|
+
if (PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')) {
|
|
10
|
+
this.observer = new PerformanceObserver(list => {
|
|
11
|
+
if (!this.paused) {
|
|
12
|
+
// only handle batches when tracking is not paused
|
|
13
|
+
this.handleBatch(list.getEntries());
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
this.observer.observe({
|
|
17
|
+
type: 'long-animation-frame',
|
|
18
|
+
buffered: options.initial
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
handleBatch(batch) {
|
|
23
|
+
let len = this.longestAnimationFrames.length;
|
|
24
|
+
for (let batchIndex = 0; batchIndex < batch.length; batchIndex++) {
|
|
25
|
+
if (batch[batchIndex].duration < this.options.reportingThreshold) {
|
|
26
|
+
// If the long frame entry had a duration less than the reporting
|
|
27
|
+
// threshold it's not eligible for tracking
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const longAnimationFrameEntry = Object.assign(batch[batchIndex], {
|
|
31
|
+
runningFeatures: Array.from(this.options.insmSession.runningFeatures)
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Not yet at capacity: append and update min tracking incrementally
|
|
35
|
+
if (len < this.options.limit) {
|
|
36
|
+
this.longestAnimationFrames[len] = longAnimationFrameEntry;
|
|
37
|
+
if (len === 0 || longAnimationFrameEntry.duration < this.minimumDuration) {
|
|
38
|
+
this.minimumDuration = longAnimationFrameEntry.duration;
|
|
39
|
+
this.minimumIndex = len;
|
|
40
|
+
}
|
|
41
|
+
len++;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// At capacity: only do work if we beat the current min
|
|
46
|
+
if (longAnimationFrameEntry.duration <= this.minimumDuration) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Replace the current min
|
|
51
|
+
this.longestAnimationFrames[this.minimumIndex] = longAnimationFrameEntry;
|
|
52
|
+
let _possiblyNewMinimumIndex = 0;
|
|
53
|
+
let _possibleNewMinimumDuration = this.longestAnimationFrames[0].duration;
|
|
54
|
+
for (let i = 1; i < this.options.limit; i++) {
|
|
55
|
+
if (this.longestAnimationFrames[i].duration < _possibleNewMinimumDuration) {
|
|
56
|
+
_possiblyNewMinimumIndex = i;
|
|
57
|
+
_possibleNewMinimumDuration = this.longestAnimationFrames[i].duration;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Update the min tracking
|
|
62
|
+
this.minimumIndex = _possiblyNewMinimumIndex;
|
|
63
|
+
this.minimumDuration = _possibleNewMinimumDuration;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Pauses tracking
|
|
69
|
+
*/
|
|
70
|
+
pause() {
|
|
71
|
+
this.paused = true;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Resumes tracking
|
|
76
|
+
*/
|
|
77
|
+
resume() {
|
|
78
|
+
this.paused = false;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Returns the current tracked longest animation frames sorted by duration
|
|
83
|
+
*/
|
|
84
|
+
get current() {
|
|
85
|
+
const copy = this.longestAnimationFrames.slice();
|
|
86
|
+
copy.sort((a, b) => b.duration - a.duration);
|
|
87
|
+
return copy;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Cleans up the performance tracking (tracking cannot be resumed following this).
|
|
92
|
+
*/
|
|
93
|
+
cleanup() {
|
|
94
|
+
var _this$observer;
|
|
95
|
+
(_this$observer = this.observer) === null || _this$observer === void 0 ? void 0 : _this$observer.disconnect();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Based on https://github.com/GoogleChrome/web-vitals/blob/1b872cf5f2159e8ace0e98d55d8eb54fb09adfbe/src/types.ts#L129
|
|
100
|
+
|
|
101
|
+
// Based on https://github.com/GoogleChrome/web-vitals/blob/1b872cf5f2159e8ace0e98d55d8eb54fb09adfbe/src/types.ts#L129
|
package/dist/esm/index.js
CHANGED
|
@@ -9,8 +9,6 @@ export function init(options) {
|
|
|
9
9
|
}
|
|
10
10
|
function insmInitialised() {
|
|
11
11
|
if (!initialisedInsm) {
|
|
12
|
-
// eslint-disable-next-line no-console
|
|
13
|
-
console.error('INSM used when not initialised');
|
|
14
12
|
return false;
|
|
15
13
|
}
|
|
16
14
|
return true;
|
|
@@ -35,6 +33,11 @@ export var insm = {
|
|
|
35
33
|
initialisedInsm.start(experienceKey, experienceProperties);
|
|
36
34
|
}
|
|
37
35
|
},
|
|
36
|
+
overrideExperienceKey: function overrideExperienceKey(experienceKey) {
|
|
37
|
+
if (insmInitialised()) {
|
|
38
|
+
initialisedInsm.overrideExperienceKey(experienceKey);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
38
41
|
stopEarly: function stopEarly(reasonKey, description) {
|
|
39
42
|
if (insmInitialised()) {
|
|
40
43
|
initialisedInsm.stopEarly(reasonKey, description);
|
package/dist/esm/insm-session.js
CHANGED
|
@@ -6,7 +6,10 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
6
6
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
7
7
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
8
8
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
9
|
+
import Bowser from 'bowser-ultralight';
|
|
10
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
9
11
|
import { PeriodTracking } from './insm-period';
|
|
12
|
+
import { LongAnimationFrameMeasurer } from './session-measurers/LongAnimationFrameMeasurer';
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* Only intended for internal use.
|
|
@@ -24,16 +27,27 @@ export var INSMSession = /*#__PURE__*/function () {
|
|
|
24
27
|
this.experienceProperties = experienceProperties;
|
|
25
28
|
this.insm = insm;
|
|
26
29
|
this.periodTracking = new PeriodTracking(this);
|
|
30
|
+
this.longAnimationFrameMeasurer = new LongAnimationFrameMeasurer({
|
|
31
|
+
initial: this.experienceProperties.initial,
|
|
32
|
+
limit: 3,
|
|
33
|
+
insmSession: this,
|
|
34
|
+
reportingThreshold: 500
|
|
35
|
+
});
|
|
27
36
|
|
|
28
37
|
/**
|
|
29
38
|
* Note: Events are not reliably fired from mobile browsers (ie. when a browser is closed when not in use)
|
|
30
39
|
*/
|
|
31
40
|
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Adds a feature to the currently running session
|
|
35
|
-
*/
|
|
36
41
|
return _createClass(INSMSession, [{
|
|
42
|
+
key: "updateExperienceKey",
|
|
43
|
+
value: function updateExperienceKey(experienceKey) {
|
|
44
|
+
this.experienceKey = experienceKey;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Adds a feature to the currently running session
|
|
49
|
+
*/
|
|
50
|
+
}, {
|
|
37
51
|
key: "startFeature",
|
|
38
52
|
value: function startFeature(featureName) {
|
|
39
53
|
var _this$periodTracking;
|
|
@@ -166,13 +180,58 @@ export var INSMSession = /*#__PURE__*/function () {
|
|
|
166
180
|
duration: duration
|
|
167
181
|
},
|
|
168
182
|
periods: periodResults,
|
|
169
|
-
endDetails: endDetails
|
|
183
|
+
endDetails: endDetails,
|
|
184
|
+
longAnimationFrames: this.longAnimationFrameMeasurer.current
|
|
170
185
|
}),
|
|
186
|
+
deviceDetails: expValEquals('cc_editor_interactivity_monitoring', 'isEnabled', true) ? getDeviceDetails() : undefined,
|
|
171
187
|
highPriority: true,
|
|
172
188
|
tags: ['editor'],
|
|
173
189
|
source: 'unknown'
|
|
174
190
|
};
|
|
175
191
|
(_this$insm$analyticsW = this.insm.analyticsWebClient) === null || _this$insm$analyticsW === void 0 || _this$insm$analyticsW.sendOperationalEvent(operationalEvent);
|
|
192
|
+
this.longAnimationFrameMeasurer.cleanup();
|
|
176
193
|
}
|
|
177
194
|
}]);
|
|
178
|
-
}();
|
|
195
|
+
}();
|
|
196
|
+
|
|
197
|
+
// Functionality vendored from UFO
|
|
198
|
+
function getDeviceDetails() {
|
|
199
|
+
var _navigator$connection, _navigator$connection2, _navigator$connection3;
|
|
200
|
+
var telemetry = {};
|
|
201
|
+
|
|
202
|
+
// /platform/packages/data/ufo-internal/src/core/publisher/plugins/browser.ts
|
|
203
|
+
if (Bowser.getParser) {
|
|
204
|
+
var _ref;
|
|
205
|
+
var browser = Bowser.getParser(((_ref = typeof window !== 'undefined' && !!window ? window : undefined) === null || _ref === void 0 || (_ref = _ref.navigator) === null || _ref === void 0 ? void 0 : _ref.userAgent) || '');
|
|
206
|
+
Object.assign(telemetry, {
|
|
207
|
+
'event:browser:name': browser.getBrowserName(),
|
|
208
|
+
'event:browser:version': browser.getBrowserVersion()
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// /platform/packages/data/ufo-internal/src/core/publisher/plugins/cpus.ts
|
|
213
|
+
Object.assign(telemetry, {
|
|
214
|
+
'event:cpus': navigator.hardwareConcurrency
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// /platform/packages/data/ufo-internal/src/core/publisher/plugins/memory.ts
|
|
218
|
+
// @ts-ignore: deviceMemory is exposed in some browsers
|
|
219
|
+
Object.assign(telemetry, {
|
|
220
|
+
'event:memory': navigator.deviceMemory
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// /platform/packages/data/ufo-internal/src/core/publisher/plugins/network.ts
|
|
224
|
+
Object.assign(telemetry, {
|
|
225
|
+
// Network
|
|
226
|
+
// @ts-ignore: connection is available in some browsers
|
|
227
|
+
// eslint-disable-next-line compat/compat
|
|
228
|
+
'event:network:effectiveType': (_navigator$connection = navigator.connection) === null || _navigator$connection === void 0 ? void 0 : _navigator$connection.effectiveType,
|
|
229
|
+
// @ts-ignore: connection is available in some browsers
|
|
230
|
+
// eslint-disable-next-line compat/compat
|
|
231
|
+
'event:network:rtt': (_navigator$connection2 = navigator.connection) === null || _navigator$connection2 === void 0 ? void 0 : _navigator$connection2.rtt,
|
|
232
|
+
// @ts-ignore: connection is available in some browsers
|
|
233
|
+
// eslint-disable-next-line compat/compat
|
|
234
|
+
'event:network:downlink': (_navigator$connection3 = navigator.connection) === null || _navigator$connection3 === void 0 ? void 0 : _navigator$connection3.downlink
|
|
235
|
+
});
|
|
236
|
+
return telemetry;
|
|
237
|
+
}
|
package/dist/esm/insm.js
CHANGED
|
@@ -50,10 +50,11 @@ export var INSM = /*#__PURE__*/function () {
|
|
|
50
50
|
return _createClass(INSM, [{
|
|
51
51
|
key: "startHeavyTask",
|
|
52
52
|
value: function startHeavyTask(heavyTaskName) {
|
|
53
|
-
var _this$runningSession2, _this$runningSession3;
|
|
53
|
+
var _this$runningSession2, _this$runningSession3, _this$session;
|
|
54
54
|
this.runningHeavyTasks.add(heavyTaskName);
|
|
55
55
|
(_this$runningSession2 = this.runningSession) === null || _this$runningSession2 === void 0 || (_this$runningSession2 = _this$runningSession2.periodTracking) === null || _this$runningSession2 === void 0 || _this$runningSession2.startHeavyTask(heavyTaskName);
|
|
56
56
|
(_this$runningSession3 = this.runningSession) === null || _this$runningSession3 === void 0 || _this$runningSession3.periodTracking.pause(heavyTaskName);
|
|
57
|
+
(_this$session = this.session) === null || _this$session === void 0 || _this$session.longAnimationFrameMeasurer.pause();
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
/**
|
|
@@ -65,6 +66,10 @@ export var INSM = /*#__PURE__*/function () {
|
|
|
65
66
|
var _this$runningSession4;
|
|
66
67
|
this.runningHeavyTasks.delete(heavyTaskName);
|
|
67
68
|
(_this$runningSession4 = this.runningSession) === null || _this$runningSession4 === void 0 || _this$runningSession4.periodTracking.resume(heavyTaskName);
|
|
69
|
+
if (this.runningHeavyTasks.size === 0) {
|
|
70
|
+
var _this$session2;
|
|
71
|
+
(_this$session2 = this.session) === null || _this$session2 === void 0 || _this$session2.longAnimationFrameMeasurer.resume();
|
|
72
|
+
}
|
|
68
73
|
}
|
|
69
74
|
|
|
70
75
|
/**
|
|
@@ -93,10 +98,31 @@ export var INSM = /*#__PURE__*/function () {
|
|
|
93
98
|
contentId: experienceProperties.contentId
|
|
94
99
|
});
|
|
95
100
|
}
|
|
101
|
+
this.lastStartedExperienceProperties = experienceProperties;
|
|
96
102
|
if ((_this$options$experie = this.options.experiences[experienceKey]) !== null && _this$options$experie !== void 0 && _this$options$experie.enabled) {
|
|
97
103
|
this.runningSession = new INSMSession(experienceKey, experienceProperties, this);
|
|
98
104
|
}
|
|
99
105
|
}
|
|
106
|
+
}, {
|
|
107
|
+
key: "overrideExperienceKey",
|
|
108
|
+
value:
|
|
109
|
+
/**
|
|
110
|
+
* Call this to update the name of the running session after it's started
|
|
111
|
+
* In the case it's been started with an unregistered name, and there is not running
|
|
112
|
+
* session. This will also trigger the session being started.
|
|
113
|
+
*/
|
|
114
|
+
function overrideExperienceKey(experienceKey) {
|
|
115
|
+
if (this.runningSession !== undefined) {
|
|
116
|
+
// If there is a running session - we update its name
|
|
117
|
+
this.runningSession.updateExperienceKey(experienceKey);
|
|
118
|
+
} else {
|
|
119
|
+
var _this$options$experie2;
|
|
120
|
+
// otherwise - we assume the last session was not registered, and start it with the new name
|
|
121
|
+
if ((_this$options$experie2 = this.options.experiences[experienceKey]) !== null && _this$options$experie2 !== void 0 && _this$options$experie2.enabled && this.lastStartedExperienceProperties) {
|
|
122
|
+
this.runningSession = new INSMSession(experienceKey, this.lastStartedExperienceProperties, this);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
100
126
|
|
|
101
127
|
/**
|
|
102
128
|
* This prematurely halts any running experience measurement. It's expected to be used in
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
3
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
4
|
+
export var LongAnimationFrameMeasurer = /*#__PURE__*/function () {
|
|
5
|
+
function LongAnimationFrameMeasurer(options) {
|
|
6
|
+
var _this = this;
|
|
7
|
+
_classCallCheck(this, LongAnimationFrameMeasurer);
|
|
8
|
+
_defineProperty(this, "longestAnimationFrames", []);
|
|
9
|
+
_defineProperty(this, "minimumIndex", -1);
|
|
10
|
+
_defineProperty(this, "minimumDuration", Infinity);
|
|
11
|
+
this.options = options;
|
|
12
|
+
this.paused = options.insmSession.insm.runningHeavyTasks.size !== 0;
|
|
13
|
+
if (PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')) {
|
|
14
|
+
this.observer = new PerformanceObserver(function (list) {
|
|
15
|
+
if (!_this.paused) {
|
|
16
|
+
// only handle batches when tracking is not paused
|
|
17
|
+
_this.handleBatch(list.getEntries());
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
this.observer.observe({
|
|
21
|
+
type: 'long-animation-frame',
|
|
22
|
+
buffered: options.initial
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return _createClass(LongAnimationFrameMeasurer, [{
|
|
27
|
+
key: "handleBatch",
|
|
28
|
+
value: function handleBatch(batch) {
|
|
29
|
+
var len = this.longestAnimationFrames.length;
|
|
30
|
+
for (var batchIndex = 0; batchIndex < batch.length; batchIndex++) {
|
|
31
|
+
if (batch[batchIndex].duration < this.options.reportingThreshold) {
|
|
32
|
+
// If the long frame entry had a duration less than the reporting
|
|
33
|
+
// threshold it's not eligible for tracking
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
var longAnimationFrameEntry = Object.assign(batch[batchIndex], {
|
|
37
|
+
runningFeatures: Array.from(this.options.insmSession.runningFeatures)
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Not yet at capacity: append and update min tracking incrementally
|
|
41
|
+
if (len < this.options.limit) {
|
|
42
|
+
this.longestAnimationFrames[len] = longAnimationFrameEntry;
|
|
43
|
+
if (len === 0 || longAnimationFrameEntry.duration < this.minimumDuration) {
|
|
44
|
+
this.minimumDuration = longAnimationFrameEntry.duration;
|
|
45
|
+
this.minimumIndex = len;
|
|
46
|
+
}
|
|
47
|
+
len++;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// At capacity: only do work if we beat the current min
|
|
52
|
+
if (longAnimationFrameEntry.duration <= this.minimumDuration) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Replace the current min
|
|
57
|
+
this.longestAnimationFrames[this.minimumIndex] = longAnimationFrameEntry;
|
|
58
|
+
var _possiblyNewMinimumIndex = 0;
|
|
59
|
+
var _possibleNewMinimumDuration = this.longestAnimationFrames[0].duration;
|
|
60
|
+
for (var i = 1; i < this.options.limit; i++) {
|
|
61
|
+
if (this.longestAnimationFrames[i].duration < _possibleNewMinimumDuration) {
|
|
62
|
+
_possiblyNewMinimumIndex = i;
|
|
63
|
+
_possibleNewMinimumDuration = this.longestAnimationFrames[i].duration;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Update the min tracking
|
|
68
|
+
this.minimumIndex = _possiblyNewMinimumIndex;
|
|
69
|
+
this.minimumDuration = _possibleNewMinimumDuration;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Pauses tracking
|
|
75
|
+
*/
|
|
76
|
+
}, {
|
|
77
|
+
key: "pause",
|
|
78
|
+
value: function pause() {
|
|
79
|
+
this.paused = true;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Resumes tracking
|
|
84
|
+
*/
|
|
85
|
+
}, {
|
|
86
|
+
key: "resume",
|
|
87
|
+
value: function resume() {
|
|
88
|
+
this.paused = false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Returns the current tracked longest animation frames sorted by duration
|
|
93
|
+
*/
|
|
94
|
+
}, {
|
|
95
|
+
key: "current",
|
|
96
|
+
get: function get() {
|
|
97
|
+
var copy = this.longestAnimationFrames.slice();
|
|
98
|
+
copy.sort(function (a, b) {
|
|
99
|
+
return b.duration - a.duration;
|
|
100
|
+
});
|
|
101
|
+
return copy;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Cleans up the performance tracking (tracking cannot be resumed following this).
|
|
106
|
+
*/
|
|
107
|
+
}, {
|
|
108
|
+
key: "cleanup",
|
|
109
|
+
value: function cleanup() {
|
|
110
|
+
var _this$observer;
|
|
111
|
+
(_this$observer = this.observer) === null || _this$observer === void 0 || _this$observer.disconnect();
|
|
112
|
+
}
|
|
113
|
+
}]);
|
|
114
|
+
}();
|
|
115
|
+
|
|
116
|
+
// Based on https://github.com/GoogleChrome/web-vitals/blob/1b872cf5f2159e8ace0e98d55d8eb54fb09adfbe/src/types.ts#L129
|
|
117
|
+
|
|
118
|
+
// Based on https://github.com/GoogleChrome/web-vitals/blob/1b872cf5f2159e8ace0e98d55d8eb54fb09adfbe/src/types.ts#L129
|
package/dist/types/index.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ export declare function init(options: INSMOptions): void;
|
|
|
8
8
|
/**
|
|
9
9
|
* **In**teractivity **s**ession **m**onitoring
|
|
10
10
|
*/
|
|
11
|
-
export declare const insm: Pick<INSM, 'start' | 'stopEarly' | 'startHeavyTask' | 'endHeavyTask'> & {
|
|
11
|
+
export declare const insm: Pick<INSM, 'start' | 'stopEarly' | 'startHeavyTask' | 'endHeavyTask' | 'overrideExperienceKey'> & {
|
|
12
12
|
session: Pick<INSMSession, 'details' | 'startFeature' | 'endFeature' | 'addProperties'> | undefined;
|
|
13
13
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { INSM } from './insm';
|
|
2
2
|
import type { AddedProperties, ExperienceProperties } from './types';
|
|
3
3
|
import { PeriodTracking } from './insm-period';
|
|
4
|
+
import { LongAnimationFrameMeasurer } from './session-measurers/LongAnimationFrameMeasurer';
|
|
4
5
|
/**
|
|
5
6
|
* Only intended for internal use.
|
|
6
7
|
*
|
|
@@ -15,7 +16,9 @@ export declare class INSMSession {
|
|
|
15
16
|
private addedProperties;
|
|
16
17
|
runningFeatures: Set<string>;
|
|
17
18
|
periodTracking: PeriodTracking;
|
|
19
|
+
longAnimationFrameMeasurer: LongAnimationFrameMeasurer;
|
|
18
20
|
constructor(experienceKey: string, experienceProperties: ExperienceProperties, insm: INSM);
|
|
21
|
+
updateExperienceKey(experienceKey: string): void;
|
|
19
22
|
/**
|
|
20
23
|
* Adds a feature to the currently running session
|
|
21
24
|
*/
|
|
@@ -84,8 +87,8 @@ export declare class INSMSession {
|
|
|
84
87
|
} | {
|
|
85
88
|
stoppedBy: 'beforeunload';
|
|
86
89
|
} | {
|
|
87
|
-
stoppedBy: 'early-stop';
|
|
88
|
-
reason: string;
|
|
89
90
|
description?: string;
|
|
91
|
+
reason: string;
|
|
92
|
+
stoppedBy: 'early-stop';
|
|
90
93
|
}): void;
|
|
91
94
|
}
|
package/dist/types/insm.d.ts
CHANGED
|
@@ -41,6 +41,13 @@ export declare class INSM {
|
|
|
41
41
|
* ```
|
|
42
42
|
*/
|
|
43
43
|
start(experienceKey: string, experienceProperties: ExperienceProperties): void;
|
|
44
|
+
private lastStartedExperienceProperties;
|
|
45
|
+
/**
|
|
46
|
+
* Call this to update the name of the running session after it's started
|
|
47
|
+
* In the case it's been started with an unregistered name, and there is not running
|
|
48
|
+
* session. This will also trigger the session being started.
|
|
49
|
+
*/
|
|
50
|
+
overrideExperienceKey(experienceKey: string): void;
|
|
44
51
|
/**
|
|
45
52
|
* This prematurely halts any running experience measurement. It's expected to be used in
|
|
46
53
|
* scenarios such as when error boundaries are hit.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { INSMSession } from '../insm-session';
|
|
2
|
+
type LongAnimationFrameMeasurerOptions = {
|
|
3
|
+
initial: boolean;
|
|
4
|
+
limit: number;
|
|
5
|
+
insmSession: INSMSession;
|
|
6
|
+
reportingThreshold: number;
|
|
7
|
+
};
|
|
8
|
+
export declare class LongAnimationFrameMeasurer {
|
|
9
|
+
private observer?;
|
|
10
|
+
private longestAnimationFrames;
|
|
11
|
+
private options;
|
|
12
|
+
private paused;
|
|
13
|
+
private minimumIndex;
|
|
14
|
+
private minimumDuration;
|
|
15
|
+
constructor(options: LongAnimationFrameMeasurerOptions);
|
|
16
|
+
private handleBatch;
|
|
17
|
+
/**
|
|
18
|
+
* Pauses tracking
|
|
19
|
+
*/
|
|
20
|
+
pause(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Resumes tracking
|
|
23
|
+
*/
|
|
24
|
+
resume(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Returns the current tracked longest animation frames sorted by duration
|
|
27
|
+
*/
|
|
28
|
+
get current(): PerformanceLongAnimationFrameTiming[];
|
|
29
|
+
/**
|
|
30
|
+
* Cleans up the performance tracking (tracking cannot be resumed following this).
|
|
31
|
+
*/
|
|
32
|
+
cleanup(): void;
|
|
33
|
+
}
|
|
34
|
+
interface PerformanceScriptTiming extends PerformanceEntry {
|
|
35
|
+
readonly startTime: DOMHighResTimeStamp;
|
|
36
|
+
readonly duration: DOMHighResTimeStamp;
|
|
37
|
+
readonly name: string;
|
|
38
|
+
readonly entryType: string;
|
|
39
|
+
readonly invokerType: 'classic-script' | 'module-script' | 'event-listener' | 'user-callback' | 'resolve-promise' | 'reject-promise';
|
|
40
|
+
readonly invoker: string;
|
|
41
|
+
readonly executionStart: DOMHighResTimeStamp;
|
|
42
|
+
readonly sourceURL: string;
|
|
43
|
+
readonly sourceFunctionName: string;
|
|
44
|
+
readonly sourceCharPosition: number;
|
|
45
|
+
readonly pauseDuration: DOMHighResTimeStamp;
|
|
46
|
+
readonly forcedStyleAndLayoutDuration: DOMHighResTimeStamp;
|
|
47
|
+
readonly window?: Window;
|
|
48
|
+
readonly windowAttribution: 'self' | 'descendant' | 'ancestor' | 'same-page' | 'other';
|
|
49
|
+
}
|
|
50
|
+
interface PerformanceLongAnimationFrameTiming extends PerformanceEntry {
|
|
51
|
+
readonly startTime: DOMHighResTimeStamp;
|
|
52
|
+
readonly duration: DOMHighResTimeStamp;
|
|
53
|
+
readonly name: string;
|
|
54
|
+
readonly entryType: string;
|
|
55
|
+
readonly renderStart: DOMHighResTimeStamp;
|
|
56
|
+
readonly styleAndLayoutStart: DOMHighResTimeStamp;
|
|
57
|
+
readonly blockingDuration: DOMHighResTimeStamp;
|
|
58
|
+
readonly firstUIEventTimestamp: DOMHighResTimeStamp;
|
|
59
|
+
readonly scripts: PerformanceScriptTiming[];
|
|
60
|
+
}
|
|
61
|
+
export {};
|
|
@@ -8,6 +8,6 @@ export declare function init(options: INSMOptions): void;
|
|
|
8
8
|
/**
|
|
9
9
|
* **In**teractivity **s**ession **m**onitoring
|
|
10
10
|
*/
|
|
11
|
-
export declare const insm: Pick<INSM, 'start' | 'stopEarly' | 'startHeavyTask' | 'endHeavyTask'> & {
|
|
11
|
+
export declare const insm: Pick<INSM, 'start' | 'stopEarly' | 'startHeavyTask' | 'endHeavyTask' | 'overrideExperienceKey'> & {
|
|
12
12
|
session: Pick<INSMSession, 'details' | 'startFeature' | 'endFeature' | 'addProperties'> | undefined;
|
|
13
13
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { INSM } from './insm';
|
|
2
2
|
import type { AddedProperties, ExperienceProperties } from './types';
|
|
3
3
|
import { PeriodTracking } from './insm-period';
|
|
4
|
+
import { LongAnimationFrameMeasurer } from './session-measurers/LongAnimationFrameMeasurer';
|
|
4
5
|
/**
|
|
5
6
|
* Only intended for internal use.
|
|
6
7
|
*
|
|
@@ -15,7 +16,9 @@ export declare class INSMSession {
|
|
|
15
16
|
private addedProperties;
|
|
16
17
|
runningFeatures: Set<string>;
|
|
17
18
|
periodTracking: PeriodTracking;
|
|
19
|
+
longAnimationFrameMeasurer: LongAnimationFrameMeasurer;
|
|
18
20
|
constructor(experienceKey: string, experienceProperties: ExperienceProperties, insm: INSM);
|
|
21
|
+
updateExperienceKey(experienceKey: string): void;
|
|
19
22
|
/**
|
|
20
23
|
* Adds a feature to the currently running session
|
|
21
24
|
*/
|
|
@@ -84,8 +87,8 @@ export declare class INSMSession {
|
|
|
84
87
|
} | {
|
|
85
88
|
stoppedBy: 'beforeunload';
|
|
86
89
|
} | {
|
|
87
|
-
stoppedBy: 'early-stop';
|
|
88
|
-
reason: string;
|
|
89
90
|
description?: string;
|
|
91
|
+
reason: string;
|
|
92
|
+
stoppedBy: 'early-stop';
|
|
90
93
|
}): void;
|
|
91
94
|
}
|
|
@@ -44,6 +44,13 @@ export declare class INSM {
|
|
|
44
44
|
* ```
|
|
45
45
|
*/
|
|
46
46
|
start(experienceKey: string, experienceProperties: ExperienceProperties): void;
|
|
47
|
+
private lastStartedExperienceProperties;
|
|
48
|
+
/**
|
|
49
|
+
* Call this to update the name of the running session after it's started
|
|
50
|
+
* In the case it's been started with an unregistered name, and there is not running
|
|
51
|
+
* session. This will also trigger the session being started.
|
|
52
|
+
*/
|
|
53
|
+
overrideExperienceKey(experienceKey: string): void;
|
|
47
54
|
/**
|
|
48
55
|
* This prematurely halts any running experience measurement. It's expected to be used in
|
|
49
56
|
* scenarios such as when error boundaries are hit.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { INSMSession } from '../insm-session';
|
|
2
|
+
type LongAnimationFrameMeasurerOptions = {
|
|
3
|
+
initial: boolean;
|
|
4
|
+
limit: number;
|
|
5
|
+
insmSession: INSMSession;
|
|
6
|
+
reportingThreshold: number;
|
|
7
|
+
};
|
|
8
|
+
export declare class LongAnimationFrameMeasurer {
|
|
9
|
+
private observer?;
|
|
10
|
+
private longestAnimationFrames;
|
|
11
|
+
private options;
|
|
12
|
+
private paused;
|
|
13
|
+
private minimumIndex;
|
|
14
|
+
private minimumDuration;
|
|
15
|
+
constructor(options: LongAnimationFrameMeasurerOptions);
|
|
16
|
+
private handleBatch;
|
|
17
|
+
/**
|
|
18
|
+
* Pauses tracking
|
|
19
|
+
*/
|
|
20
|
+
pause(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Resumes tracking
|
|
23
|
+
*/
|
|
24
|
+
resume(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Returns the current tracked longest animation frames sorted by duration
|
|
27
|
+
*/
|
|
28
|
+
get current(): PerformanceLongAnimationFrameTiming[];
|
|
29
|
+
/**
|
|
30
|
+
* Cleans up the performance tracking (tracking cannot be resumed following this).
|
|
31
|
+
*/
|
|
32
|
+
cleanup(): void;
|
|
33
|
+
}
|
|
34
|
+
interface PerformanceScriptTiming extends PerformanceEntry {
|
|
35
|
+
readonly startTime: DOMHighResTimeStamp;
|
|
36
|
+
readonly duration: DOMHighResTimeStamp;
|
|
37
|
+
readonly name: string;
|
|
38
|
+
readonly entryType: string;
|
|
39
|
+
readonly invokerType: 'classic-script' | 'module-script' | 'event-listener' | 'user-callback' | 'resolve-promise' | 'reject-promise';
|
|
40
|
+
readonly invoker: string;
|
|
41
|
+
readonly executionStart: DOMHighResTimeStamp;
|
|
42
|
+
readonly sourceURL: string;
|
|
43
|
+
readonly sourceFunctionName: string;
|
|
44
|
+
readonly sourceCharPosition: number;
|
|
45
|
+
readonly pauseDuration: DOMHighResTimeStamp;
|
|
46
|
+
readonly forcedStyleAndLayoutDuration: DOMHighResTimeStamp;
|
|
47
|
+
readonly window?: Window;
|
|
48
|
+
readonly windowAttribution: 'self' | 'descendant' | 'ancestor' | 'same-page' | 'other';
|
|
49
|
+
}
|
|
50
|
+
interface PerformanceLongAnimationFrameTiming extends PerformanceEntry {
|
|
51
|
+
readonly startTime: DOMHighResTimeStamp;
|
|
52
|
+
readonly duration: DOMHighResTimeStamp;
|
|
53
|
+
readonly name: string;
|
|
54
|
+
readonly entryType: string;
|
|
55
|
+
readonly renderStart: DOMHighResTimeStamp;
|
|
56
|
+
readonly styleAndLayoutStart: DOMHighResTimeStamp;
|
|
57
|
+
readonly blockingDuration: DOMHighResTimeStamp;
|
|
58
|
+
readonly firstUIEventTimestamp: DOMHighResTimeStamp;
|
|
59
|
+
readonly scripts: PerformanceScriptTiming[];
|
|
60
|
+
}
|
|
61
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/insm",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "INSM tooling measures user-perceived interactivity of a page",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -25,9 +25,10 @@
|
|
|
25
25
|
},
|
|
26
26
|
"atlaskit:src": "src/index.ts",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@atlaskit/analytics-listeners": "^9.
|
|
29
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
30
|
-
"@babel/runtime": "^7.0.0"
|
|
28
|
+
"@atlaskit/analytics-listeners": "^9.1.0",
|
|
29
|
+
"@atlaskit/tmp-editor-statsig": "^13.0.0",
|
|
30
|
+
"@babel/runtime": "^7.0.0",
|
|
31
|
+
"bowser-ultralight": "^1.0.6"
|
|
31
32
|
},
|
|
32
33
|
"peerDependencies": {
|
|
33
34
|
"react": "^18.2.0"
|