@spotify-confidence/session-recording 0.18.11 → 0.18.13
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 +25 -0
- package/dist/index.cjs +14 -13
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +14 -13
- package/dist/{uploader-CkAqZXJP.js → uploader-DG4NHFfc.cjs} +119 -2
- package/dist/{uploader-CcDy4aME.cjs → uploader-Dj4tUQ6O.js} +96 -13
- package/dist/worker.cjs +1 -1
- package/dist/worker.js +1 -1
- package/package.json +3 -3
- package/src/index.ts +4 -3
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.18.13](https://github.com/spotify/confidence-sdk-js/compare/session-recording-v0.18.12...session-recording-v0.18.13) (2026-09-09)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Dependencies
|
|
7
|
+
|
|
8
|
+
* The following workspace dependencies were updated
|
|
9
|
+
* dependencies
|
|
10
|
+
* @spotify-confidence/csr-common bumped to 0.18.10
|
|
11
|
+
* @spotify-confidence/csr-recorder bumped to 0.17.18
|
|
12
|
+
|
|
13
|
+
## [0.18.12](https://github.com/spotify/confidence-sdk-js/compare/session-recording-v0.18.11...session-recording-v0.18.12) (2026-09-07)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### 🐛 Bug Fixes
|
|
17
|
+
|
|
18
|
+
* stop passive recording frames extending sessions ([#449](https://github.com/spotify/confidence-sdk-js/issues/449)) ([df763a1](https://github.com/spotify/confidence-sdk-js/commit/df763a10d6f16ce5b871530ca3fe8b5c153c16d7))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Dependencies
|
|
22
|
+
|
|
23
|
+
* The following workspace dependencies were updated
|
|
24
|
+
* dependencies
|
|
25
|
+
* @spotify-confidence/csr-common bumped to 0.18.9
|
|
26
|
+
* @spotify-confidence/csr-recorder bumped to 0.17.17
|
|
27
|
+
|
|
3
28
|
## [0.18.11](https://github.com/spotify/confidence-sdk-js/compare/session-recording-v0.18.10...session-recording-v0.18.11) (2026-08-28)
|
|
4
29
|
|
|
5
30
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_uploader = require("./uploader-
|
|
2
|
+
const require_uploader = require("./uploader-DG4NHFfc.cjs");
|
|
3
3
|
const VALID_KEY_PATTERN = /^[a-zA-Z0-9_.-]+$/;
|
|
4
4
|
function validateKey(key) {
|
|
5
5
|
if (typeof key !== "string" || key.length === 0) return "key is empty";
|
|
@@ -118,7 +118,7 @@ var Recorder = class Recorder {
|
|
|
118
118
|
if (typeof document !== "undefined") {
|
|
119
119
|
this.visibilityHandler = () => {
|
|
120
120
|
const data = {
|
|
121
|
-
plugin:
|
|
121
|
+
plugin: require_uploader.RecordingPluginName.TabVisibility,
|
|
122
122
|
payload: { hidden: document.hidden }
|
|
123
123
|
};
|
|
124
124
|
this.onEvent({
|
|
@@ -140,7 +140,7 @@ var Recorder = class Recorder {
|
|
|
140
140
|
}
|
|
141
141
|
emitNetworkRequest(payload) {
|
|
142
142
|
const data = {
|
|
143
|
-
plugin:
|
|
143
|
+
plugin: require_uploader.RecordingPluginName.NetworkRequest,
|
|
144
144
|
payload
|
|
145
145
|
};
|
|
146
146
|
this.onEvent({
|
|
@@ -234,12 +234,13 @@ var Recorder = class Recorder {
|
|
|
234
234
|
};
|
|
235
235
|
}
|
|
236
236
|
parameterizeHref(href) {
|
|
237
|
+
const strippedHref = require_uploader.stripUrlQueryAndHash(href);
|
|
237
238
|
try {
|
|
238
|
-
const url = new URL(
|
|
239
|
+
const url = new URL(strippedHref);
|
|
239
240
|
url.pathname = this.parameterizeRoute(url.pathname);
|
|
240
241
|
return url.toString();
|
|
241
242
|
} catch (_e) {
|
|
242
|
-
return this.parameterizeRoute(
|
|
243
|
+
return this.parameterizeRoute(strippedHref);
|
|
243
244
|
}
|
|
244
245
|
}
|
|
245
246
|
emitRouteChange(from, to, trigger) {
|
|
@@ -248,7 +249,7 @@ var Recorder = class Recorder {
|
|
|
248
249
|
const paramTo = this.parameterizeRoute(to);
|
|
249
250
|
if (paramFrom === paramTo) return;
|
|
250
251
|
const data = {
|
|
251
|
-
plugin:
|
|
252
|
+
plugin: require_uploader.RecordingPluginName.RouteChange,
|
|
252
253
|
payload: {
|
|
253
254
|
from: paramFrom,
|
|
254
255
|
to: paramTo,
|
|
@@ -11153,7 +11154,7 @@ function labelBlockedElement(node) {
|
|
|
11153
11154
|
*/
|
|
11154
11155
|
function blockedElementLabelsPlugin() {
|
|
11155
11156
|
return {
|
|
11156
|
-
name:
|
|
11157
|
+
name: require_uploader.RecordingPluginName.BlockedElementLabels,
|
|
11157
11158
|
options: {},
|
|
11158
11159
|
observer: () => () => {},
|
|
11159
11160
|
eventProcessor: (event) => {
|
|
@@ -11171,7 +11172,7 @@ function blockedElementLabelsPlugin() {
|
|
|
11171
11172
|
function clipboardActionsPlugin() {
|
|
11172
11173
|
let getId;
|
|
11173
11174
|
return {
|
|
11174
|
-
name:
|
|
11175
|
+
name: require_uploader.RecordingPluginName.Clipboard,
|
|
11175
11176
|
options: {},
|
|
11176
11177
|
getMirror: ({ nodeMirror }) => {
|
|
11177
11178
|
getId = (node) => nodeMirror.getId(node);
|
|
@@ -11203,7 +11204,7 @@ function clipboardActionsPlugin() {
|
|
|
11203
11204
|
function clickModifiersPlugin() {
|
|
11204
11205
|
let pendingClick = null;
|
|
11205
11206
|
return {
|
|
11206
|
-
name:
|
|
11207
|
+
name: require_uploader.RecordingPluginName.ClickModifiers,
|
|
11207
11208
|
options: {},
|
|
11208
11209
|
observer: (_callback, win) => {
|
|
11209
11210
|
const onClick = (event) => {
|
|
@@ -11326,7 +11327,7 @@ function observeFlags(onFlagWrite) {
|
|
|
11326
11327
|
}
|
|
11327
11328
|
//#endregion
|
|
11328
11329
|
//#region src/version.ts
|
|
11329
|
-
const SDK_VERSION = "0.18.
|
|
11330
|
+
const SDK_VERSION = "0.18.13";
|
|
11330
11331
|
//#endregion
|
|
11331
11332
|
//#region src/index.ts
|
|
11332
11333
|
const DEFAULT_API_URL = "https://recording.confidence.dev";
|
|
@@ -11404,7 +11405,7 @@ function initSessionRecorder(options) {
|
|
|
11404
11405
|
stopRecorder = record(sendEvent, recordingConfig);
|
|
11405
11406
|
stopObservingFlags = observeFlags(({ flagKey, variant, assignmentOrigin }) => {
|
|
11406
11407
|
const data = {
|
|
11407
|
-
plugin:
|
|
11408
|
+
plugin: require_uploader.RecordingPluginName.FlagEvaluation,
|
|
11408
11409
|
payload: {
|
|
11409
11410
|
flagKey,
|
|
11410
11411
|
variant,
|
|
@@ -11454,7 +11455,7 @@ function initSessionRecorder(options) {
|
|
|
11454
11455
|
return;
|
|
11455
11456
|
}
|
|
11456
11457
|
const data = {
|
|
11457
|
-
plugin:
|
|
11458
|
+
plugin: require_uploader.RecordingPluginName.Tag,
|
|
11458
11459
|
payload: value !== void 0 ? {
|
|
11459
11460
|
key,
|
|
11460
11461
|
value
|
|
@@ -11478,7 +11479,7 @@ function initSessionRecorder(options) {
|
|
|
11478
11479
|
return;
|
|
11479
11480
|
}
|
|
11480
11481
|
const data = {
|
|
11481
|
-
plugin:
|
|
11482
|
+
plugin: require_uploader.RecordingPluginName.Measure,
|
|
11482
11483
|
payload: value !== void 0 ? {
|
|
11483
11484
|
key,
|
|
11484
11485
|
value
|
package/dist/index.d.cts
CHANGED
|
@@ -25,7 +25,7 @@ type UserAgentContext = {
|
|
|
25
25
|
screenWidth?: number;
|
|
26
26
|
screenHeight?: number;
|
|
27
27
|
devicePixelRatio?: number; /** Initial document URI — without query/hash to avoid leaking PII. */
|
|
28
|
-
uri?: string;
|
|
28
|
+
uri?: string; /** Document referrer — without query/hash to avoid leaking PII. */
|
|
29
29
|
referrer?: string;
|
|
30
30
|
};
|
|
31
31
|
interface ClientContext {
|
package/dist/index.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ type UserAgentContext = {
|
|
|
25
25
|
screenWidth?: number;
|
|
26
26
|
screenHeight?: number;
|
|
27
27
|
devicePixelRatio?: number; /** Initial document URI — without query/hash to avoid leaking PII. */
|
|
28
|
-
uri?: string;
|
|
28
|
+
uri?: string; /** Document referrer — without query/hash to avoid leaking PII. */
|
|
29
29
|
referrer?: string;
|
|
30
30
|
};
|
|
31
31
|
interface ClientContext {
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as createUploader } from "./uploader-
|
|
1
|
+
import { i as RecordingPluginName, r as stripUrlQueryAndHash, t as createUploader } from "./uploader-Dj4tUQ6O.js";
|
|
2
2
|
const VALID_KEY_PATTERN = /^[a-zA-Z0-9_.-]+$/;
|
|
3
3
|
function validateKey(key) {
|
|
4
4
|
if (typeof key !== "string" || key.length === 0) return "key is empty";
|
|
@@ -117,7 +117,7 @@ var Recorder = class Recorder {
|
|
|
117
117
|
if (typeof document !== "undefined") {
|
|
118
118
|
this.visibilityHandler = () => {
|
|
119
119
|
const data = {
|
|
120
|
-
plugin:
|
|
120
|
+
plugin: RecordingPluginName.TabVisibility,
|
|
121
121
|
payload: { hidden: document.hidden }
|
|
122
122
|
};
|
|
123
123
|
this.onEvent({
|
|
@@ -139,7 +139,7 @@ var Recorder = class Recorder {
|
|
|
139
139
|
}
|
|
140
140
|
emitNetworkRequest(payload) {
|
|
141
141
|
const data = {
|
|
142
|
-
plugin:
|
|
142
|
+
plugin: RecordingPluginName.NetworkRequest,
|
|
143
143
|
payload
|
|
144
144
|
};
|
|
145
145
|
this.onEvent({
|
|
@@ -233,12 +233,13 @@ var Recorder = class Recorder {
|
|
|
233
233
|
};
|
|
234
234
|
}
|
|
235
235
|
parameterizeHref(href) {
|
|
236
|
+
const strippedHref = stripUrlQueryAndHash(href);
|
|
236
237
|
try {
|
|
237
|
-
const url = new URL(
|
|
238
|
+
const url = new URL(strippedHref);
|
|
238
239
|
url.pathname = this.parameterizeRoute(url.pathname);
|
|
239
240
|
return url.toString();
|
|
240
241
|
} catch (_e) {
|
|
241
|
-
return this.parameterizeRoute(
|
|
242
|
+
return this.parameterizeRoute(strippedHref);
|
|
242
243
|
}
|
|
243
244
|
}
|
|
244
245
|
emitRouteChange(from, to, trigger) {
|
|
@@ -247,7 +248,7 @@ var Recorder = class Recorder {
|
|
|
247
248
|
const paramTo = this.parameterizeRoute(to);
|
|
248
249
|
if (paramFrom === paramTo) return;
|
|
249
250
|
const data = {
|
|
250
|
-
plugin:
|
|
251
|
+
plugin: RecordingPluginName.RouteChange,
|
|
251
252
|
payload: {
|
|
252
253
|
from: paramFrom,
|
|
253
254
|
to: paramTo,
|
|
@@ -11134,7 +11135,7 @@ function labelBlockedElement(node) {
|
|
|
11134
11135
|
*/
|
|
11135
11136
|
function blockedElementLabelsPlugin() {
|
|
11136
11137
|
return {
|
|
11137
|
-
name:
|
|
11138
|
+
name: RecordingPluginName.BlockedElementLabels,
|
|
11138
11139
|
options: {},
|
|
11139
11140
|
observer: () => () => {},
|
|
11140
11141
|
eventProcessor: (event) => {
|
|
@@ -11152,7 +11153,7 @@ function blockedElementLabelsPlugin() {
|
|
|
11152
11153
|
function clipboardActionsPlugin() {
|
|
11153
11154
|
let getId;
|
|
11154
11155
|
return {
|
|
11155
|
-
name:
|
|
11156
|
+
name: RecordingPluginName.Clipboard,
|
|
11156
11157
|
options: {},
|
|
11157
11158
|
getMirror: ({ nodeMirror }) => {
|
|
11158
11159
|
getId = (node) => nodeMirror.getId(node);
|
|
@@ -11184,7 +11185,7 @@ function clipboardActionsPlugin() {
|
|
|
11184
11185
|
function clickModifiersPlugin() {
|
|
11185
11186
|
let pendingClick = null;
|
|
11186
11187
|
return {
|
|
11187
|
-
name:
|
|
11188
|
+
name: RecordingPluginName.ClickModifiers,
|
|
11188
11189
|
options: {},
|
|
11189
11190
|
observer: (_callback, win) => {
|
|
11190
11191
|
const onClick = (event) => {
|
|
@@ -11307,7 +11308,7 @@ function observeFlags(onFlagWrite) {
|
|
|
11307
11308
|
}
|
|
11308
11309
|
//#endregion
|
|
11309
11310
|
//#region src/version.ts
|
|
11310
|
-
const SDK_VERSION = "0.18.
|
|
11311
|
+
const SDK_VERSION = "0.18.13";
|
|
11311
11312
|
//#endregion
|
|
11312
11313
|
//#region src/index.ts
|
|
11313
11314
|
const DEFAULT_API_URL = "https://recording.confidence.dev";
|
|
@@ -11385,7 +11386,7 @@ function initSessionRecorder(options) {
|
|
|
11385
11386
|
stopRecorder = record(sendEvent, recordingConfig);
|
|
11386
11387
|
stopObservingFlags = observeFlags(({ flagKey, variant, assignmentOrigin }) => {
|
|
11387
11388
|
const data = {
|
|
11388
|
-
plugin:
|
|
11389
|
+
plugin: RecordingPluginName.FlagEvaluation,
|
|
11389
11390
|
payload: {
|
|
11390
11391
|
flagKey,
|
|
11391
11392
|
variant,
|
|
@@ -11435,7 +11436,7 @@ function initSessionRecorder(options) {
|
|
|
11435
11436
|
return;
|
|
11436
11437
|
}
|
|
11437
11438
|
const data = {
|
|
11438
|
-
plugin:
|
|
11439
|
+
plugin: RecordingPluginName.Tag,
|
|
11439
11440
|
payload: value !== void 0 ? {
|
|
11440
11441
|
key,
|
|
11441
11442
|
value
|
|
@@ -11459,7 +11460,7 @@ function initSessionRecorder(options) {
|
|
|
11459
11460
|
return;
|
|
11460
11461
|
}
|
|
11461
11462
|
const data = {
|
|
11462
|
-
plugin:
|
|
11463
|
+
plugin: RecordingPluginName.Measure,
|
|
11463
11464
|
payload: value !== void 0 ? {
|
|
11464
11465
|
key,
|
|
11465
11466
|
value
|
|
@@ -21,6 +21,99 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
enumerable: true
|
|
22
22
|
}) : target, mod));
|
|
23
23
|
//#endregion
|
|
24
|
+
//#region ../csr-common/src/events.ts
|
|
25
|
+
const RecordingCustomEventTag = {
|
|
26
|
+
RageClick: "csr:rageClick",
|
|
27
|
+
FormFieldReEdit: "csr:formFieldReEdit",
|
|
28
|
+
ScrollBack: "csr:scrollBack",
|
|
29
|
+
Click: "csr:click",
|
|
30
|
+
Input: "csr:input",
|
|
31
|
+
DeadClick: "csr:deadClick",
|
|
32
|
+
TabUnfocus: "csr:tabUnfocus",
|
|
33
|
+
TabRefocus: "csr:tabRefocus",
|
|
34
|
+
RouteChange: "csr:routeChange",
|
|
35
|
+
ErrorMessage: "csr:errorMessage",
|
|
36
|
+
DialogOpened: "csr:dialogOpened",
|
|
37
|
+
IdleGap: "csr:idleGap",
|
|
38
|
+
AwayGap: "csr:awayGap"
|
|
39
|
+
};
|
|
40
|
+
const RecordingPluginName = {
|
|
41
|
+
BlockedElementLabels: "csr/blocked-element-labels@1",
|
|
42
|
+
Clipboard: "csr/clipboard@1",
|
|
43
|
+
ClickModifiers: "csr/click-modifiers@1",
|
|
44
|
+
TabVisibility: "csr:tabVisibility",
|
|
45
|
+
ConsoleLog: "rrweb/console@1",
|
|
46
|
+
NetworkRequest: "csr:networkRequest",
|
|
47
|
+
RouteChange: "csr:routeChange",
|
|
48
|
+
Tag: "csr:tag",
|
|
49
|
+
Measure: "csr:measure",
|
|
50
|
+
FlagEvaluation: "csr:flagEvaluation"
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region ../csr-common/src/url.ts
|
|
54
|
+
/** Remove query strings and fragments, including from relative or malformed URLs. */
|
|
55
|
+
function stripUrlQueryAndHash(url) {
|
|
56
|
+
return url.split(/[?#]/, 1)[0];
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region ../csr-common/src/metrics.ts
|
|
60
|
+
const RecordingMetricKey = {
|
|
61
|
+
Click: "clicks",
|
|
62
|
+
Input: "inputs",
|
|
63
|
+
RageClick: "rageClicks",
|
|
64
|
+
DeadClick: "deadClicks",
|
|
65
|
+
ScrollBack: "scrollBacks",
|
|
66
|
+
TabUnfocus: "tabUnfocuses",
|
|
67
|
+
ErrorMessage: "errorMessages",
|
|
68
|
+
FailedNetworkRequest: "networkRequestsFailed",
|
|
69
|
+
NetworkRequest: "networkRequests",
|
|
70
|
+
ConsoleLog: "consoleLogs",
|
|
71
|
+
ConsoleWarning: "consoleWarnings",
|
|
72
|
+
ConsoleError: "consoleErrors",
|
|
73
|
+
RouteChange: "routeChanges"
|
|
74
|
+
};
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region ../csr-common/src/session-activity.ts
|
|
77
|
+
const USER_INTERACTION_SOURCES = new Set([
|
|
78
|
+
1,
|
|
79
|
+
2,
|
|
80
|
+
3,
|
|
81
|
+
5,
|
|
82
|
+
6,
|
|
83
|
+
7,
|
|
84
|
+
12,
|
|
85
|
+
14
|
|
86
|
+
]);
|
|
87
|
+
const USER_INTERACTION_TAGS = new Set([
|
|
88
|
+
RecordingCustomEventTag.Click,
|
|
89
|
+
RecordingCustomEventTag.Input,
|
|
90
|
+
RecordingCustomEventTag.RageClick,
|
|
91
|
+
RecordingCustomEventTag.DeadClick,
|
|
92
|
+
RecordingCustomEventTag.ScrollBack,
|
|
93
|
+
RecordingCustomEventTag.TabUnfocus,
|
|
94
|
+
RecordingCustomEventTag.TabRefocus,
|
|
95
|
+
RecordingCustomEventTag.FormFieldReEdit,
|
|
96
|
+
RecordingCustomEventTag.RouteChange
|
|
97
|
+
]);
|
|
98
|
+
const USER_INTERACTION_PLUGINS = new Set([RecordingPluginName.RouteChange]);
|
|
99
|
+
new Set([
|
|
100
|
+
RecordingMetricKey.Click,
|
|
101
|
+
RecordingMetricKey.Input,
|
|
102
|
+
RecordingMetricKey.RageClick,
|
|
103
|
+
RecordingMetricKey.DeadClick,
|
|
104
|
+
RecordingMetricKey.ScrollBack,
|
|
105
|
+
RecordingMetricKey.TabUnfocus,
|
|
106
|
+
RecordingMetricKey.RouteChange
|
|
107
|
+
]);
|
|
108
|
+
const isObject = (value) => typeof value === "object" && value !== null;
|
|
109
|
+
const isUserInteractionEvent = (event) => {
|
|
110
|
+
if (!isObject(event) || !isObject(event.data)) return false;
|
|
111
|
+
if (event.type === 3) return typeof event.data.source === "number" && USER_INTERACTION_SOURCES.has(event.data.source);
|
|
112
|
+
if (event.type === 5) return typeof event.data.tag === "string" && USER_INTERACTION_TAGS.has(event.data.tag);
|
|
113
|
+
return event.type === 6 && typeof event.data.plugin === "string" && USER_INTERACTION_PLUGINS.has(event.data.plugin);
|
|
114
|
+
};
|
|
115
|
+
const isSessionActivityEvent = (event) => isObject(event) && event.type === 4 || isUserInteractionEvent(event);
|
|
116
|
+
//#endregion
|
|
24
117
|
//#region ../csr-common/src/uploader/client-context.ts
|
|
25
118
|
var import_es5 = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
26
119
|
(function(e, t) {
|
|
@@ -1758,7 +1851,7 @@ function collectUserAgentContext() {
|
|
|
1758
1851
|
screenHeight: window.screen.height,
|
|
1759
1852
|
devicePixelRatio: window.devicePixelRatio,
|
|
1760
1853
|
uri: `${window.location.origin}${window.location.pathname}`,
|
|
1761
|
-
referrer: document.referrer
|
|
1854
|
+
referrer: stripUrlQueryAndHash(document.referrer)
|
|
1762
1855
|
};
|
|
1763
1856
|
}
|
|
1764
1857
|
//#endregion
|
|
@@ -1897,6 +1990,7 @@ async function createUploader(opts) {
|
|
|
1897
1990
|
tabId: effectiveTabId,
|
|
1898
1991
|
eventCounter: counter,
|
|
1899
1992
|
data: event,
|
|
1993
|
+
userActivity: isSessionActivityEvent(event),
|
|
1900
1994
|
...nextAdoptionMeta ?? {}
|
|
1901
1995
|
};
|
|
1902
1996
|
counter += 1;
|
|
@@ -2060,4 +2154,27 @@ function writeCounter(counter) {
|
|
|
2060
2154
|
sessionStorage.setItem(STORAGE_COUNTER, String(counter));
|
|
2061
2155
|
}
|
|
2062
2156
|
//#endregion
|
|
2063
|
-
|
|
2157
|
+
Object.defineProperty(exports, "RecordingPluginName", {
|
|
2158
|
+
enumerable: true,
|
|
2159
|
+
get: function() {
|
|
2160
|
+
return RecordingPluginName;
|
|
2161
|
+
}
|
|
2162
|
+
});
|
|
2163
|
+
Object.defineProperty(exports, "createUploader", {
|
|
2164
|
+
enumerable: true,
|
|
2165
|
+
get: function() {
|
|
2166
|
+
return createUploader;
|
|
2167
|
+
}
|
|
2168
|
+
});
|
|
2169
|
+
Object.defineProperty(exports, "stripUrlQueryAndHash", {
|
|
2170
|
+
enumerable: true,
|
|
2171
|
+
get: function() {
|
|
2172
|
+
return stripUrlQueryAndHash;
|
|
2173
|
+
}
|
|
2174
|
+
});
|
|
2175
|
+
Object.defineProperty(exports, "workerScript", {
|
|
2176
|
+
enumerable: true,
|
|
2177
|
+
get: function() {
|
|
2178
|
+
return workerScript;
|
|
2179
|
+
}
|
|
2180
|
+
});
|
|
@@ -21,6 +21,99 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
enumerable: true
|
|
22
22
|
}) : target, mod));
|
|
23
23
|
//#endregion
|
|
24
|
+
//#region ../csr-common/src/events.ts
|
|
25
|
+
const RecordingCustomEventTag = {
|
|
26
|
+
RageClick: "csr:rageClick",
|
|
27
|
+
FormFieldReEdit: "csr:formFieldReEdit",
|
|
28
|
+
ScrollBack: "csr:scrollBack",
|
|
29
|
+
Click: "csr:click",
|
|
30
|
+
Input: "csr:input",
|
|
31
|
+
DeadClick: "csr:deadClick",
|
|
32
|
+
TabUnfocus: "csr:tabUnfocus",
|
|
33
|
+
TabRefocus: "csr:tabRefocus",
|
|
34
|
+
RouteChange: "csr:routeChange",
|
|
35
|
+
ErrorMessage: "csr:errorMessage",
|
|
36
|
+
DialogOpened: "csr:dialogOpened",
|
|
37
|
+
IdleGap: "csr:idleGap",
|
|
38
|
+
AwayGap: "csr:awayGap"
|
|
39
|
+
};
|
|
40
|
+
const RecordingPluginName = {
|
|
41
|
+
BlockedElementLabels: "csr/blocked-element-labels@1",
|
|
42
|
+
Clipboard: "csr/clipboard@1",
|
|
43
|
+
ClickModifiers: "csr/click-modifiers@1",
|
|
44
|
+
TabVisibility: "csr:tabVisibility",
|
|
45
|
+
ConsoleLog: "rrweb/console@1",
|
|
46
|
+
NetworkRequest: "csr:networkRequest",
|
|
47
|
+
RouteChange: "csr:routeChange",
|
|
48
|
+
Tag: "csr:tag",
|
|
49
|
+
Measure: "csr:measure",
|
|
50
|
+
FlagEvaluation: "csr:flagEvaluation"
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region ../csr-common/src/url.ts
|
|
54
|
+
/** Remove query strings and fragments, including from relative or malformed URLs. */
|
|
55
|
+
function stripUrlQueryAndHash(url) {
|
|
56
|
+
return url.split(/[?#]/, 1)[0];
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region ../csr-common/src/metrics.ts
|
|
60
|
+
const RecordingMetricKey = {
|
|
61
|
+
Click: "clicks",
|
|
62
|
+
Input: "inputs",
|
|
63
|
+
RageClick: "rageClicks",
|
|
64
|
+
DeadClick: "deadClicks",
|
|
65
|
+
ScrollBack: "scrollBacks",
|
|
66
|
+
TabUnfocus: "tabUnfocuses",
|
|
67
|
+
ErrorMessage: "errorMessages",
|
|
68
|
+
FailedNetworkRequest: "networkRequestsFailed",
|
|
69
|
+
NetworkRequest: "networkRequests",
|
|
70
|
+
ConsoleLog: "consoleLogs",
|
|
71
|
+
ConsoleWarning: "consoleWarnings",
|
|
72
|
+
ConsoleError: "consoleErrors",
|
|
73
|
+
RouteChange: "routeChanges"
|
|
74
|
+
};
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region ../csr-common/src/session-activity.ts
|
|
77
|
+
const USER_INTERACTION_SOURCES = new Set([
|
|
78
|
+
1,
|
|
79
|
+
2,
|
|
80
|
+
3,
|
|
81
|
+
5,
|
|
82
|
+
6,
|
|
83
|
+
7,
|
|
84
|
+
12,
|
|
85
|
+
14
|
|
86
|
+
]);
|
|
87
|
+
const USER_INTERACTION_TAGS = new Set([
|
|
88
|
+
RecordingCustomEventTag.Click,
|
|
89
|
+
RecordingCustomEventTag.Input,
|
|
90
|
+
RecordingCustomEventTag.RageClick,
|
|
91
|
+
RecordingCustomEventTag.DeadClick,
|
|
92
|
+
RecordingCustomEventTag.ScrollBack,
|
|
93
|
+
RecordingCustomEventTag.TabUnfocus,
|
|
94
|
+
RecordingCustomEventTag.TabRefocus,
|
|
95
|
+
RecordingCustomEventTag.FormFieldReEdit,
|
|
96
|
+
RecordingCustomEventTag.RouteChange
|
|
97
|
+
]);
|
|
98
|
+
const USER_INTERACTION_PLUGINS = new Set([RecordingPluginName.RouteChange]);
|
|
99
|
+
new Set([
|
|
100
|
+
RecordingMetricKey.Click,
|
|
101
|
+
RecordingMetricKey.Input,
|
|
102
|
+
RecordingMetricKey.RageClick,
|
|
103
|
+
RecordingMetricKey.DeadClick,
|
|
104
|
+
RecordingMetricKey.ScrollBack,
|
|
105
|
+
RecordingMetricKey.TabUnfocus,
|
|
106
|
+
RecordingMetricKey.RouteChange
|
|
107
|
+
]);
|
|
108
|
+
const isObject = (value) => typeof value === "object" && value !== null;
|
|
109
|
+
const isUserInteractionEvent = (event) => {
|
|
110
|
+
if (!isObject(event) || !isObject(event.data)) return false;
|
|
111
|
+
if (event.type === 3) return typeof event.data.source === "number" && USER_INTERACTION_SOURCES.has(event.data.source);
|
|
112
|
+
if (event.type === 5) return typeof event.data.tag === "string" && USER_INTERACTION_TAGS.has(event.data.tag);
|
|
113
|
+
return event.type === 6 && typeof event.data.plugin === "string" && USER_INTERACTION_PLUGINS.has(event.data.plugin);
|
|
114
|
+
};
|
|
115
|
+
const isSessionActivityEvent = (event) => isObject(event) && event.type === 4 || isUserInteractionEvent(event);
|
|
116
|
+
//#endregion
|
|
24
117
|
//#region ../csr-common/src/uploader/client-context.ts
|
|
25
118
|
var import_es5 = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
26
119
|
(function(e, t) {
|
|
@@ -1758,7 +1851,7 @@ function collectUserAgentContext() {
|
|
|
1758
1851
|
screenHeight: window.screen.height,
|
|
1759
1852
|
devicePixelRatio: window.devicePixelRatio,
|
|
1760
1853
|
uri: `${window.location.origin}${window.location.pathname}`,
|
|
1761
|
-
referrer: document.referrer
|
|
1854
|
+
referrer: stripUrlQueryAndHash(document.referrer)
|
|
1762
1855
|
};
|
|
1763
1856
|
}
|
|
1764
1857
|
//#endregion
|
|
@@ -1897,6 +1990,7 @@ async function createUploader(opts) {
|
|
|
1897
1990
|
tabId: effectiveTabId,
|
|
1898
1991
|
eventCounter: counter,
|
|
1899
1992
|
data: event,
|
|
1993
|
+
userActivity: isSessionActivityEvent(event),
|
|
1900
1994
|
...nextAdoptionMeta ?? {}
|
|
1901
1995
|
};
|
|
1902
1996
|
counter += 1;
|
|
@@ -2060,15 +2154,4 @@ function writeCounter(counter) {
|
|
|
2060
2154
|
sessionStorage.setItem(STORAGE_COUNTER, String(counter));
|
|
2061
2155
|
}
|
|
2062
2156
|
//#endregion
|
|
2063
|
-
|
|
2064
|
-
enumerable: true,
|
|
2065
|
-
get: function() {
|
|
2066
|
-
return createUploader;
|
|
2067
|
-
}
|
|
2068
|
-
});
|
|
2069
|
-
Object.defineProperty(exports, "workerScript", {
|
|
2070
|
-
enumerable: true,
|
|
2071
|
-
get: function() {
|
|
2072
|
-
return workerScript;
|
|
2073
|
-
}
|
|
2074
|
-
});
|
|
2157
|
+
export { RecordingPluginName as i, workerScript as n, stripUrlQueryAndHash as r, createUploader as t };
|
package/dist/worker.cjs
CHANGED
package/dist/worker.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as workerScript } from "./uploader-
|
|
1
|
+
import { n as workerScript } from "./uploader-Dj4tUQ6O.js";
|
|
2
2
|
export { workerScript };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spotify-confidence/session-recording",
|
|
3
3
|
"license": "Apache-2.0",
|
|
4
|
-
"version": "0.18.
|
|
4
|
+
"version": "0.18.13",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/spotify/confidence-sdk-js.git",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@spotify-confidence/csr-common": "0.18.
|
|
45
|
-
"@spotify-confidence/csr-recorder": "0.17.
|
|
44
|
+
"@spotify-confidence/csr-common": "0.18.10",
|
|
45
|
+
"@spotify-confidence/csr-recorder": "0.17.18"
|
|
46
46
|
},
|
|
47
47
|
"module": "./dist/index.js",
|
|
48
48
|
"exports": {
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { record } from '@spotify-confidence/csr-recorder';
|
|
|
2
2
|
import type { ConsoleLogLevel } from '@spotify-confidence/csr-common';
|
|
3
3
|
import {
|
|
4
4
|
RecordingEventType,
|
|
5
|
+
RecordingPluginName,
|
|
5
6
|
type TagPluginData,
|
|
6
7
|
type MeasurePluginData,
|
|
7
8
|
type FlagEvaluationPluginData,
|
|
@@ -175,7 +176,7 @@ export function initSessionRecorder(options: InitSessionRecorderOptions): Sessio
|
|
|
175
176
|
|
|
176
177
|
stopObservingFlags = observeFlags(({ flagKey, variant, assignmentOrigin }) => {
|
|
177
178
|
const data: FlagEvaluationPluginData = {
|
|
178
|
-
plugin:
|
|
179
|
+
plugin: RecordingPluginName.FlagEvaluation,
|
|
179
180
|
payload: { flagKey, variant, assignmentOrigin },
|
|
180
181
|
};
|
|
181
182
|
sendEvent?.({
|
|
@@ -225,7 +226,7 @@ export function initSessionRecorder(options: InitSessionRecorderOptions): Sessio
|
|
|
225
226
|
return;
|
|
226
227
|
}
|
|
227
228
|
const data: TagPluginData = {
|
|
228
|
-
plugin:
|
|
229
|
+
plugin: RecordingPluginName.Tag,
|
|
229
230
|
payload: value !== undefined ? { key, value } : { key },
|
|
230
231
|
};
|
|
231
232
|
sendEvent?.({
|
|
@@ -246,7 +247,7 @@ export function initSessionRecorder(options: InitSessionRecorderOptions): Sessio
|
|
|
246
247
|
return;
|
|
247
248
|
}
|
|
248
249
|
const data: MeasurePluginData = {
|
|
249
|
-
plugin:
|
|
250
|
+
plugin: RecordingPluginName.Measure,
|
|
250
251
|
payload: value !== undefined ? { key, value } : { key },
|
|
251
252
|
};
|
|
252
253
|
sendEvent?.({
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = '0.18.
|
|
1
|
+
export const SDK_VERSION = '0.18.13';
|