@spotify-confidence/csr-common 0.18.8 → 0.18.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,82 +1,4 @@
1
- //#region src/events.ts
2
- /**
3
- * Mirrors rrweb's serialized-node types but decoupled — we own the enum.
4
- */
5
- let SerializedNodeType = /* @__PURE__ */ function(SerializedNodeType) {
6
- SerializedNodeType[SerializedNodeType["Document"] = 0] = "Document";
7
- SerializedNodeType[SerializedNodeType["DocumentType"] = 1] = "DocumentType";
8
- SerializedNodeType[SerializedNodeType["Element"] = 2] = "Element";
9
- SerializedNodeType[SerializedNodeType["Text"] = 3] = "Text";
10
- SerializedNodeType[SerializedNodeType["CDATA"] = 4] = "CDATA";
11
- SerializedNodeType[SerializedNodeType["Comment"] = 5] = "Comment";
12
- return SerializedNodeType;
13
- }({});
14
- /**
15
- * Mirrors rrweb event types but decoupled — we own the enum.
16
- */
17
- let RecordingEventType = /* @__PURE__ */ function(RecordingEventType) {
18
- RecordingEventType[RecordingEventType["DomContentLoaded"] = 0] = "DomContentLoaded";
19
- RecordingEventType[RecordingEventType["Load"] = 1] = "Load";
20
- RecordingEventType[RecordingEventType["FullSnapshot"] = 2] = "FullSnapshot";
21
- RecordingEventType[RecordingEventType["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
22
- RecordingEventType[RecordingEventType["Meta"] = 4] = "Meta";
23
- RecordingEventType[RecordingEventType["Custom"] = 5] = "Custom";
24
- RecordingEventType[RecordingEventType["Plugin"] = 6] = "Plugin";
25
- return RecordingEventType;
26
- }({});
27
- /**
28
- * Incremental snapshot sub-types.
29
- */
30
- let IncrementalSource = /* @__PURE__ */ function(IncrementalSource) {
31
- IncrementalSource[IncrementalSource["Mutation"] = 0] = "Mutation";
32
- IncrementalSource[IncrementalSource["MouseMove"] = 1] = "MouseMove";
33
- IncrementalSource[IncrementalSource["MouseInteraction"] = 2] = "MouseInteraction";
34
- IncrementalSource[IncrementalSource["Scroll"] = 3] = "Scroll";
35
- IncrementalSource[IncrementalSource["ViewportResize"] = 4] = "ViewportResize";
36
- IncrementalSource[IncrementalSource["Input"] = 5] = "Input";
37
- IncrementalSource[IncrementalSource["TouchMove"] = 6] = "TouchMove";
38
- IncrementalSource[IncrementalSource["MediaInteraction"] = 7] = "MediaInteraction";
39
- IncrementalSource[IncrementalSource["StyleSheetRule"] = 8] = "StyleSheetRule";
40
- IncrementalSource[IncrementalSource["CanvasMutation"] = 9] = "CanvasMutation";
41
- IncrementalSource[IncrementalSource["Font"] = 10] = "Font";
42
- IncrementalSource[IncrementalSource["Log"] = 11] = "Log";
43
- IncrementalSource[IncrementalSource["Drag"] = 12] = "Drag";
44
- IncrementalSource[IncrementalSource["StyleDeclaration"] = 13] = "StyleDeclaration";
45
- IncrementalSource[IncrementalSource["Selection"] = 14] = "Selection";
46
- IncrementalSource[IncrementalSource["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
47
- return IncrementalSource;
48
- }({});
49
- /**
50
- * From rrweb MouseInteractions.
51
- */
52
- let MouseInteractions = /* @__PURE__ */ function(MouseInteractions) {
53
- MouseInteractions[MouseInteractions["MouseUp"] = 0] = "MouseUp";
54
- MouseInteractions[MouseInteractions["MouseDown"] = 1] = "MouseDown";
55
- MouseInteractions[MouseInteractions["Click"] = 2] = "Click";
56
- MouseInteractions[MouseInteractions["ContextMenu"] = 3] = "ContextMenu";
57
- MouseInteractions[MouseInteractions["DblClick"] = 4] = "DblClick";
58
- MouseInteractions[MouseInteractions["Focus"] = 5] = "Focus";
59
- MouseInteractions[MouseInteractions["Blur"] = 6] = "Blur";
60
- MouseInteractions[MouseInteractions["TouchStart"] = 7] = "TouchStart";
61
- MouseInteractions[MouseInteractions["TouchMove_Departed"] = 8] = "TouchMove_Departed";
62
- MouseInteractions[MouseInteractions["TouchEnd"] = 9] = "TouchEnd";
63
- MouseInteractions[MouseInteractions["TouchCancel"] = 10] = "TouchCancel";
64
- return MouseInteractions;
65
- }({});
66
- //#endregion
67
- //#region src/url.ts
68
- /**
69
- * Extract only the pathname from a URL, stripping origin, query string, and
70
- * hash. Used across recorder and analyzer to avoid capturing PII in route data.
71
- */
72
- function stripUrl(url) {
73
- try {
74
- return new URL(url).pathname;
75
- } catch (_e) {
76
- return url;
77
- }
78
- }
79
- //#endregion
1
+ import { a as stripUrl, c as MouseInteractions, d as RecordingPluginName, f as SerializedNodeType, i as RecordingMetricKey, l as RecordingCustomEventTag, n as isUserInteractionEvent, o as stripUrlQueryAndHash, r as isUserInteractionMetric, s as IncrementalSource, t as isSessionActivityEvent, u as RecordingEventType } from "./session-activity-tshS9Hua.js";
80
2
  //#region src/custom-event-limits.ts
81
3
  const MAX_KEY_LENGTH = 128;
82
4
  const MAX_TAG_VALUE_LENGTH = 256;
@@ -101,4 +23,4 @@ function validateMeasureValue(value) {
101
23
  return null;
102
24
  }
103
25
  //#endregion
104
- export { IncrementalSource, MAX_DISTINCT_KEYS, MAX_KEY_LENGTH, MAX_TAG_VALUE_LENGTH, MAX_VALUES_PER_KEY, MouseInteractions, RecordingEventType, SerializedNodeType, stripUrl, validateKey, validateMeasureValue, validateTagValue };
26
+ export { IncrementalSource, MAX_DISTINCT_KEYS, MAX_KEY_LENGTH, MAX_TAG_VALUE_LENGTH, MAX_VALUES_PER_KEY, MouseInteractions, RecordingCustomEventTag, RecordingEventType, RecordingMetricKey, RecordingPluginName, SerializedNodeType, isSessionActivityEvent, isUserInteractionEvent, isUserInteractionMetric, stripUrl, stripUrlQueryAndHash, validateKey, validateMeasureValue, validateTagValue };
@@ -0,0 +1,241 @@
1
+ //#region src/events.ts
2
+ /**
3
+ * Mirrors rrweb's serialized-node types but decoupled — we own the enum.
4
+ */
5
+ let SerializedNodeType = /* @__PURE__ */ function(SerializedNodeType) {
6
+ SerializedNodeType[SerializedNodeType["Document"] = 0] = "Document";
7
+ SerializedNodeType[SerializedNodeType["DocumentType"] = 1] = "DocumentType";
8
+ SerializedNodeType[SerializedNodeType["Element"] = 2] = "Element";
9
+ SerializedNodeType[SerializedNodeType["Text"] = 3] = "Text";
10
+ SerializedNodeType[SerializedNodeType["CDATA"] = 4] = "CDATA";
11
+ SerializedNodeType[SerializedNodeType["Comment"] = 5] = "Comment";
12
+ return SerializedNodeType;
13
+ }({});
14
+ /**
15
+ * Mirrors rrweb event types but decoupled — we own the enum.
16
+ */
17
+ let RecordingEventType = /* @__PURE__ */ function(RecordingEventType) {
18
+ RecordingEventType[RecordingEventType["DomContentLoaded"] = 0] = "DomContentLoaded";
19
+ RecordingEventType[RecordingEventType["Load"] = 1] = "Load";
20
+ RecordingEventType[RecordingEventType["FullSnapshot"] = 2] = "FullSnapshot";
21
+ RecordingEventType[RecordingEventType["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
22
+ RecordingEventType[RecordingEventType["Meta"] = 4] = "Meta";
23
+ RecordingEventType[RecordingEventType["Custom"] = 5] = "Custom";
24
+ RecordingEventType[RecordingEventType["Plugin"] = 6] = "Plugin";
25
+ return RecordingEventType;
26
+ }({});
27
+ const RecordingCustomEventTag = {
28
+ RageClick: "csr:rageClick",
29
+ FormFieldReEdit: "csr:formFieldReEdit",
30
+ ScrollBack: "csr:scrollBack",
31
+ Click: "csr:click",
32
+ Input: "csr:input",
33
+ DeadClick: "csr:deadClick",
34
+ TabUnfocus: "csr:tabUnfocus",
35
+ TabRefocus: "csr:tabRefocus",
36
+ RouteChange: "csr:routeChange",
37
+ ErrorMessage: "csr:errorMessage",
38
+ DialogOpened: "csr:dialogOpened",
39
+ IdleGap: "csr:idleGap",
40
+ AwayGap: "csr:awayGap"
41
+ };
42
+ const RecordingPluginName = {
43
+ BlockedElementLabels: "csr/blocked-element-labels@1",
44
+ Clipboard: "csr/clipboard@1",
45
+ ClickModifiers: "csr/click-modifiers@1",
46
+ TabVisibility: "csr:tabVisibility",
47
+ ConsoleLog: "rrweb/console@1",
48
+ NetworkRequest: "csr:networkRequest",
49
+ RouteChange: "csr:routeChange",
50
+ Tag: "csr:tag",
51
+ Measure: "csr:measure",
52
+ FlagEvaluation: "csr:flagEvaluation"
53
+ };
54
+ /**
55
+ * Incremental snapshot sub-types.
56
+ */
57
+ let IncrementalSource = /* @__PURE__ */ function(IncrementalSource) {
58
+ IncrementalSource[IncrementalSource["Mutation"] = 0] = "Mutation";
59
+ IncrementalSource[IncrementalSource["MouseMove"] = 1] = "MouseMove";
60
+ IncrementalSource[IncrementalSource["MouseInteraction"] = 2] = "MouseInteraction";
61
+ IncrementalSource[IncrementalSource["Scroll"] = 3] = "Scroll";
62
+ IncrementalSource[IncrementalSource["ViewportResize"] = 4] = "ViewportResize";
63
+ IncrementalSource[IncrementalSource["Input"] = 5] = "Input";
64
+ IncrementalSource[IncrementalSource["TouchMove"] = 6] = "TouchMove";
65
+ IncrementalSource[IncrementalSource["MediaInteraction"] = 7] = "MediaInteraction";
66
+ IncrementalSource[IncrementalSource["StyleSheetRule"] = 8] = "StyleSheetRule";
67
+ IncrementalSource[IncrementalSource["CanvasMutation"] = 9] = "CanvasMutation";
68
+ IncrementalSource[IncrementalSource["Font"] = 10] = "Font";
69
+ IncrementalSource[IncrementalSource["Log"] = 11] = "Log";
70
+ IncrementalSource[IncrementalSource["Drag"] = 12] = "Drag";
71
+ IncrementalSource[IncrementalSource["StyleDeclaration"] = 13] = "StyleDeclaration";
72
+ IncrementalSource[IncrementalSource["Selection"] = 14] = "Selection";
73
+ IncrementalSource[IncrementalSource["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
74
+ return IncrementalSource;
75
+ }({});
76
+ /**
77
+ * From rrweb MouseInteractions.
78
+ */
79
+ let MouseInteractions = /* @__PURE__ */ function(MouseInteractions) {
80
+ MouseInteractions[MouseInteractions["MouseUp"] = 0] = "MouseUp";
81
+ MouseInteractions[MouseInteractions["MouseDown"] = 1] = "MouseDown";
82
+ MouseInteractions[MouseInteractions["Click"] = 2] = "Click";
83
+ MouseInteractions[MouseInteractions["ContextMenu"] = 3] = "ContextMenu";
84
+ MouseInteractions[MouseInteractions["DblClick"] = 4] = "DblClick";
85
+ MouseInteractions[MouseInteractions["Focus"] = 5] = "Focus";
86
+ MouseInteractions[MouseInteractions["Blur"] = 6] = "Blur";
87
+ MouseInteractions[MouseInteractions["TouchStart"] = 7] = "TouchStart";
88
+ MouseInteractions[MouseInteractions["TouchMove_Departed"] = 8] = "TouchMove_Departed";
89
+ MouseInteractions[MouseInteractions["TouchEnd"] = 9] = "TouchEnd";
90
+ MouseInteractions[MouseInteractions["TouchCancel"] = 10] = "TouchCancel";
91
+ return MouseInteractions;
92
+ }({});
93
+ //#endregion
94
+ //#region src/url.ts
95
+ /** Remove query strings and fragments, including from relative or malformed URLs. */
96
+ function stripUrlQueryAndHash(url) {
97
+ return url.split(/[?#]/, 1)[0];
98
+ }
99
+ /**
100
+ * Extract only the pathname from a URL, stripping origin, query string, and
101
+ * hash. Used across recorder and analyzer to avoid capturing PII in route data.
102
+ */
103
+ function stripUrl(url) {
104
+ try {
105
+ return new URL(url).pathname;
106
+ } catch (_e) {
107
+ return url;
108
+ }
109
+ }
110
+ //#endregion
111
+ //#region src/metrics.ts
112
+ const RecordingMetricKey = {
113
+ Click: "clicks",
114
+ Input: "inputs",
115
+ RageClick: "rageClicks",
116
+ DeadClick: "deadClicks",
117
+ ScrollBack: "scrollBacks",
118
+ TabUnfocus: "tabUnfocuses",
119
+ ErrorMessage: "errorMessages",
120
+ FailedNetworkRequest: "networkRequestsFailed",
121
+ NetworkRequest: "networkRequests",
122
+ ConsoleLog: "consoleLogs",
123
+ ConsoleWarning: "consoleWarnings",
124
+ ConsoleError: "consoleErrors",
125
+ RouteChange: "routeChanges"
126
+ };
127
+ //#endregion
128
+ //#region src/session-activity.ts
129
+ const USER_INTERACTION_SOURCES = new Set([
130
+ 1,
131
+ 2,
132
+ 3,
133
+ 5,
134
+ 6,
135
+ 7,
136
+ 12,
137
+ 14
138
+ ]);
139
+ const USER_INTERACTION_TAGS = new Set([
140
+ RecordingCustomEventTag.Click,
141
+ RecordingCustomEventTag.Input,
142
+ RecordingCustomEventTag.RageClick,
143
+ RecordingCustomEventTag.DeadClick,
144
+ RecordingCustomEventTag.ScrollBack,
145
+ RecordingCustomEventTag.TabUnfocus,
146
+ RecordingCustomEventTag.TabRefocus,
147
+ RecordingCustomEventTag.FormFieldReEdit,
148
+ RecordingCustomEventTag.RouteChange
149
+ ]);
150
+ const USER_INTERACTION_PLUGINS = new Set([RecordingPluginName.RouteChange]);
151
+ const USER_INTERACTION_METRIC_KEYS = new Set([
152
+ RecordingMetricKey.Click,
153
+ RecordingMetricKey.Input,
154
+ RecordingMetricKey.RageClick,
155
+ RecordingMetricKey.DeadClick,
156
+ RecordingMetricKey.ScrollBack,
157
+ RecordingMetricKey.TabUnfocus,
158
+ RecordingMetricKey.RouteChange
159
+ ]);
160
+ const isObject = (value) => typeof value === "object" && value !== null;
161
+ const isUserInteractionEvent = (event) => {
162
+ if (!isObject(event) || !isObject(event.data)) return false;
163
+ if (event.type === 3) return typeof event.data.source === "number" && USER_INTERACTION_SOURCES.has(event.data.source);
164
+ if (event.type === 5) return typeof event.data.tag === "string" && USER_INTERACTION_TAGS.has(event.data.tag);
165
+ return event.type === 6 && typeof event.data.plugin === "string" && USER_INTERACTION_PLUGINS.has(event.data.plugin);
166
+ };
167
+ const isUserInteractionMetric = (metricKey) => USER_INTERACTION_METRIC_KEYS.has(metricKey);
168
+ const isSessionActivityEvent = (event) => isObject(event) && event.type === 4 || isUserInteractionEvent(event);
169
+ //#endregion
170
+ Object.defineProperty(exports, "IncrementalSource", {
171
+ enumerable: true,
172
+ get: function() {
173
+ return IncrementalSource;
174
+ }
175
+ });
176
+ Object.defineProperty(exports, "MouseInteractions", {
177
+ enumerable: true,
178
+ get: function() {
179
+ return MouseInteractions;
180
+ }
181
+ });
182
+ Object.defineProperty(exports, "RecordingCustomEventTag", {
183
+ enumerable: true,
184
+ get: function() {
185
+ return RecordingCustomEventTag;
186
+ }
187
+ });
188
+ Object.defineProperty(exports, "RecordingEventType", {
189
+ enumerable: true,
190
+ get: function() {
191
+ return RecordingEventType;
192
+ }
193
+ });
194
+ Object.defineProperty(exports, "RecordingMetricKey", {
195
+ enumerable: true,
196
+ get: function() {
197
+ return RecordingMetricKey;
198
+ }
199
+ });
200
+ Object.defineProperty(exports, "RecordingPluginName", {
201
+ enumerable: true,
202
+ get: function() {
203
+ return RecordingPluginName;
204
+ }
205
+ });
206
+ Object.defineProperty(exports, "SerializedNodeType", {
207
+ enumerable: true,
208
+ get: function() {
209
+ return SerializedNodeType;
210
+ }
211
+ });
212
+ Object.defineProperty(exports, "isSessionActivityEvent", {
213
+ enumerable: true,
214
+ get: function() {
215
+ return isSessionActivityEvent;
216
+ }
217
+ });
218
+ Object.defineProperty(exports, "isUserInteractionEvent", {
219
+ enumerable: true,
220
+ get: function() {
221
+ return isUserInteractionEvent;
222
+ }
223
+ });
224
+ Object.defineProperty(exports, "isUserInteractionMetric", {
225
+ enumerable: true,
226
+ get: function() {
227
+ return isUserInteractionMetric;
228
+ }
229
+ });
230
+ Object.defineProperty(exports, "stripUrl", {
231
+ enumerable: true,
232
+ get: function() {
233
+ return stripUrl;
234
+ }
235
+ });
236
+ Object.defineProperty(exports, "stripUrlQueryAndHash", {
237
+ enumerable: true,
238
+ get: function() {
239
+ return stripUrlQueryAndHash;
240
+ }
241
+ });
@@ -0,0 +1,170 @@
1
+ //#region src/events.ts
2
+ /**
3
+ * Mirrors rrweb's serialized-node types but decoupled — we own the enum.
4
+ */
5
+ let SerializedNodeType = /* @__PURE__ */ function(SerializedNodeType) {
6
+ SerializedNodeType[SerializedNodeType["Document"] = 0] = "Document";
7
+ SerializedNodeType[SerializedNodeType["DocumentType"] = 1] = "DocumentType";
8
+ SerializedNodeType[SerializedNodeType["Element"] = 2] = "Element";
9
+ SerializedNodeType[SerializedNodeType["Text"] = 3] = "Text";
10
+ SerializedNodeType[SerializedNodeType["CDATA"] = 4] = "CDATA";
11
+ SerializedNodeType[SerializedNodeType["Comment"] = 5] = "Comment";
12
+ return SerializedNodeType;
13
+ }({});
14
+ /**
15
+ * Mirrors rrweb event types but decoupled — we own the enum.
16
+ */
17
+ let RecordingEventType = /* @__PURE__ */ function(RecordingEventType) {
18
+ RecordingEventType[RecordingEventType["DomContentLoaded"] = 0] = "DomContentLoaded";
19
+ RecordingEventType[RecordingEventType["Load"] = 1] = "Load";
20
+ RecordingEventType[RecordingEventType["FullSnapshot"] = 2] = "FullSnapshot";
21
+ RecordingEventType[RecordingEventType["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
22
+ RecordingEventType[RecordingEventType["Meta"] = 4] = "Meta";
23
+ RecordingEventType[RecordingEventType["Custom"] = 5] = "Custom";
24
+ RecordingEventType[RecordingEventType["Plugin"] = 6] = "Plugin";
25
+ return RecordingEventType;
26
+ }({});
27
+ const RecordingCustomEventTag = {
28
+ RageClick: "csr:rageClick",
29
+ FormFieldReEdit: "csr:formFieldReEdit",
30
+ ScrollBack: "csr:scrollBack",
31
+ Click: "csr:click",
32
+ Input: "csr:input",
33
+ DeadClick: "csr:deadClick",
34
+ TabUnfocus: "csr:tabUnfocus",
35
+ TabRefocus: "csr:tabRefocus",
36
+ RouteChange: "csr:routeChange",
37
+ ErrorMessage: "csr:errorMessage",
38
+ DialogOpened: "csr:dialogOpened",
39
+ IdleGap: "csr:idleGap",
40
+ AwayGap: "csr:awayGap"
41
+ };
42
+ const RecordingPluginName = {
43
+ BlockedElementLabels: "csr/blocked-element-labels@1",
44
+ Clipboard: "csr/clipboard@1",
45
+ ClickModifiers: "csr/click-modifiers@1",
46
+ TabVisibility: "csr:tabVisibility",
47
+ ConsoleLog: "rrweb/console@1",
48
+ NetworkRequest: "csr:networkRequest",
49
+ RouteChange: "csr:routeChange",
50
+ Tag: "csr:tag",
51
+ Measure: "csr:measure",
52
+ FlagEvaluation: "csr:flagEvaluation"
53
+ };
54
+ /**
55
+ * Incremental snapshot sub-types.
56
+ */
57
+ let IncrementalSource = /* @__PURE__ */ function(IncrementalSource) {
58
+ IncrementalSource[IncrementalSource["Mutation"] = 0] = "Mutation";
59
+ IncrementalSource[IncrementalSource["MouseMove"] = 1] = "MouseMove";
60
+ IncrementalSource[IncrementalSource["MouseInteraction"] = 2] = "MouseInteraction";
61
+ IncrementalSource[IncrementalSource["Scroll"] = 3] = "Scroll";
62
+ IncrementalSource[IncrementalSource["ViewportResize"] = 4] = "ViewportResize";
63
+ IncrementalSource[IncrementalSource["Input"] = 5] = "Input";
64
+ IncrementalSource[IncrementalSource["TouchMove"] = 6] = "TouchMove";
65
+ IncrementalSource[IncrementalSource["MediaInteraction"] = 7] = "MediaInteraction";
66
+ IncrementalSource[IncrementalSource["StyleSheetRule"] = 8] = "StyleSheetRule";
67
+ IncrementalSource[IncrementalSource["CanvasMutation"] = 9] = "CanvasMutation";
68
+ IncrementalSource[IncrementalSource["Font"] = 10] = "Font";
69
+ IncrementalSource[IncrementalSource["Log"] = 11] = "Log";
70
+ IncrementalSource[IncrementalSource["Drag"] = 12] = "Drag";
71
+ IncrementalSource[IncrementalSource["StyleDeclaration"] = 13] = "StyleDeclaration";
72
+ IncrementalSource[IncrementalSource["Selection"] = 14] = "Selection";
73
+ IncrementalSource[IncrementalSource["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
74
+ return IncrementalSource;
75
+ }({});
76
+ /**
77
+ * From rrweb MouseInteractions.
78
+ */
79
+ let MouseInteractions = /* @__PURE__ */ function(MouseInteractions) {
80
+ MouseInteractions[MouseInteractions["MouseUp"] = 0] = "MouseUp";
81
+ MouseInteractions[MouseInteractions["MouseDown"] = 1] = "MouseDown";
82
+ MouseInteractions[MouseInteractions["Click"] = 2] = "Click";
83
+ MouseInteractions[MouseInteractions["ContextMenu"] = 3] = "ContextMenu";
84
+ MouseInteractions[MouseInteractions["DblClick"] = 4] = "DblClick";
85
+ MouseInteractions[MouseInteractions["Focus"] = 5] = "Focus";
86
+ MouseInteractions[MouseInteractions["Blur"] = 6] = "Blur";
87
+ MouseInteractions[MouseInteractions["TouchStart"] = 7] = "TouchStart";
88
+ MouseInteractions[MouseInteractions["TouchMove_Departed"] = 8] = "TouchMove_Departed";
89
+ MouseInteractions[MouseInteractions["TouchEnd"] = 9] = "TouchEnd";
90
+ MouseInteractions[MouseInteractions["TouchCancel"] = 10] = "TouchCancel";
91
+ return MouseInteractions;
92
+ }({});
93
+ //#endregion
94
+ //#region src/url.ts
95
+ /** Remove query strings and fragments, including from relative or malformed URLs. */
96
+ function stripUrlQueryAndHash(url) {
97
+ return url.split(/[?#]/, 1)[0];
98
+ }
99
+ /**
100
+ * Extract only the pathname from a URL, stripping origin, query string, and
101
+ * hash. Used across recorder and analyzer to avoid capturing PII in route data.
102
+ */
103
+ function stripUrl(url) {
104
+ try {
105
+ return new URL(url).pathname;
106
+ } catch (_e) {
107
+ return url;
108
+ }
109
+ }
110
+ //#endregion
111
+ //#region src/metrics.ts
112
+ const RecordingMetricKey = {
113
+ Click: "clicks",
114
+ Input: "inputs",
115
+ RageClick: "rageClicks",
116
+ DeadClick: "deadClicks",
117
+ ScrollBack: "scrollBacks",
118
+ TabUnfocus: "tabUnfocuses",
119
+ ErrorMessage: "errorMessages",
120
+ FailedNetworkRequest: "networkRequestsFailed",
121
+ NetworkRequest: "networkRequests",
122
+ ConsoleLog: "consoleLogs",
123
+ ConsoleWarning: "consoleWarnings",
124
+ ConsoleError: "consoleErrors",
125
+ RouteChange: "routeChanges"
126
+ };
127
+ //#endregion
128
+ //#region src/session-activity.ts
129
+ const USER_INTERACTION_SOURCES = new Set([
130
+ 1,
131
+ 2,
132
+ 3,
133
+ 5,
134
+ 6,
135
+ 7,
136
+ 12,
137
+ 14
138
+ ]);
139
+ const USER_INTERACTION_TAGS = new Set([
140
+ RecordingCustomEventTag.Click,
141
+ RecordingCustomEventTag.Input,
142
+ RecordingCustomEventTag.RageClick,
143
+ RecordingCustomEventTag.DeadClick,
144
+ RecordingCustomEventTag.ScrollBack,
145
+ RecordingCustomEventTag.TabUnfocus,
146
+ RecordingCustomEventTag.TabRefocus,
147
+ RecordingCustomEventTag.FormFieldReEdit,
148
+ RecordingCustomEventTag.RouteChange
149
+ ]);
150
+ const USER_INTERACTION_PLUGINS = new Set([RecordingPluginName.RouteChange]);
151
+ const USER_INTERACTION_METRIC_KEYS = new Set([
152
+ RecordingMetricKey.Click,
153
+ RecordingMetricKey.Input,
154
+ RecordingMetricKey.RageClick,
155
+ RecordingMetricKey.DeadClick,
156
+ RecordingMetricKey.ScrollBack,
157
+ RecordingMetricKey.TabUnfocus,
158
+ RecordingMetricKey.RouteChange
159
+ ]);
160
+ const isObject = (value) => typeof value === "object" && value !== null;
161
+ const isUserInteractionEvent = (event) => {
162
+ if (!isObject(event) || !isObject(event.data)) return false;
163
+ if (event.type === 3) return typeof event.data.source === "number" && USER_INTERACTION_SOURCES.has(event.data.source);
164
+ if (event.type === 5) return typeof event.data.tag === "string" && USER_INTERACTION_TAGS.has(event.data.tag);
165
+ return event.type === 6 && typeof event.data.plugin === "string" && USER_INTERACTION_PLUGINS.has(event.data.plugin);
166
+ };
167
+ const isUserInteractionMetric = (metricKey) => USER_INTERACTION_METRIC_KEYS.has(metricKey);
168
+ const isSessionActivityEvent = (event) => isObject(event) && event.type === 4 || isUserInteractionEvent(event);
169
+ //#endregion
170
+ export { stripUrl as a, MouseInteractions as c, RecordingPluginName as d, SerializedNodeType as f, RecordingMetricKey as i, RecordingCustomEventTag as l, isUserInteractionEvent as n, stripUrlQueryAndHash as o, isUserInteractionMetric as r, IncrementalSource as s, isSessionActivityEvent as t, RecordingEventType as u };
@@ -22,7 +22,7 @@ type UserAgentContext = {
22
22
  screenWidth?: number;
23
23
  screenHeight?: number;
24
24
  devicePixelRatio?: number; /** Initial document URI — without query/hash to avoid leaking PII. */
25
- uri?: string;
25
+ uri?: string; /** Document referrer — without query/hash to avoid leaking PII. */
26
26
  referrer?: string;
27
27
  };
28
28
  interface ClientContext {
@@ -102,6 +102,8 @@ interface Frame {
102
102
  eventCounter: number;
103
103
  /** Opaque payload from the recorder. */
104
104
  data: unknown;
105
+ /** Whether the frame should refresh the backend's session inactivity timeout. */
106
+ userActivity?: boolean;
105
107
  /** Set only on the first frame emitted after the tab was adopted into a different session. */
106
108
  adoptedFromSessionId?: string;
107
109
  /** Epoch millis of the adoption event. */
@@ -22,7 +22,7 @@ type UserAgentContext = {
22
22
  screenWidth?: number;
23
23
  screenHeight?: number;
24
24
  devicePixelRatio?: number; /** Initial document URI — without query/hash to avoid leaking PII. */
25
- uri?: string;
25
+ uri?: string; /** Document referrer — without query/hash to avoid leaking PII. */
26
26
  referrer?: string;
27
27
  };
28
28
  interface ClientContext {
@@ -102,6 +102,8 @@ interface Frame {
102
102
  eventCounter: number;
103
103
  /** Opaque payload from the recorder. */
104
104
  data: unknown;
105
+ /** Whether the frame should refresh the backend's session inactivity timeout. */
106
+ userActivity?: boolean;
105
107
  /** Set only on the first frame emitted after the tab was adopted into a different session. */
106
108
  adoptedFromSessionId?: string;
107
109
  /** Epoch millis of the adoption event. */
@@ -21,6 +21,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
21
  enumerable: true
22
22
  }) : target, mod));
23
23
  //#endregion
24
+ const require_session_activity = require("../session-activity-B8swR5Wg.cjs");
24
25
  let bowser = require("bowser");
25
26
  bowser = __toESM(bowser, 1);
26
27
  //#region src/uploader/client-context.ts
@@ -45,7 +46,7 @@ function collectUserAgentContext() {
45
46
  screenHeight: window.screen.height,
46
47
  devicePixelRatio: window.devicePixelRatio,
47
48
  uri: `${window.location.origin}${window.location.pathname}`,
48
- referrer: document.referrer
49
+ referrer: require_session_activity.stripUrlQueryAndHash(document.referrer)
49
50
  };
50
51
  }
51
52
  //#endregion
@@ -184,6 +185,7 @@ async function createUploader(opts) {
184
185
  tabId: effectiveTabId,
185
186
  eventCounter: counter,
186
187
  data: event,
188
+ userActivity: require_session_activity.isSessionActivityEvent(event),
187
189
  ...nextAdoptionMeta ?? {}
188
190
  };
189
191
  counter += 1;
@@ -1,4 +1,4 @@
1
- import { a as ContextValue, i as ClientContext, o as UserAgentContext, r as Uploader, s as collectUserAgentContext, t as CreateUploaderOptions } from "../types-CtBIVgp2.cjs";
1
+ import { a as ContextValue, i as ClientContext, o as UserAgentContext, r as Uploader, s as collectUserAgentContext, t as CreateUploaderOptions } from "../types-C3mO_2YH.cjs";
2
2
 
3
3
  //#region src/uploader/create-uploader.d.ts
4
4
  declare function createUploader(opts: CreateUploaderOptions): Promise<Uploader | null>;
@@ -1,4 +1,4 @@
1
- import { a as ContextValue, i as ClientContext, o as UserAgentContext, r as Uploader, s as collectUserAgentContext, t as CreateUploaderOptions } from "../types-CtBIVgp2.js";
1
+ import { a as ContextValue, i as ClientContext, o as UserAgentContext, r as Uploader, s as collectUserAgentContext, t as CreateUploaderOptions } from "../types-C3mO_2YH.js";
2
2
 
3
3
  //#region src/uploader/create-uploader.d.ts
4
4
  declare function createUploader(opts: CreateUploaderOptions): Promise<Uploader | null>;
@@ -1,3 +1,4 @@
1
+ import { o as stripUrlQueryAndHash, t as isSessionActivityEvent } from "../session-activity-tshS9Hua.js";
1
2
  import Bowser from "bowser";
2
3
  //#region src/uploader/client-context.ts
3
4
  function collectUserAgentContext() {
@@ -21,7 +22,7 @@ function collectUserAgentContext() {
21
22
  screenHeight: window.screen.height,
22
23
  devicePixelRatio: window.devicePixelRatio,
23
24
  uri: `${window.location.origin}${window.location.pathname}`,
24
- referrer: document.referrer
25
+ referrer: stripUrlQueryAndHash(document.referrer)
25
26
  };
26
27
  }
27
28
  //#endregion
@@ -160,6 +161,7 @@ async function createUploader(opts) {
160
161
  tabId: effectiveTabId,
161
162
  eventCounter: counter,
162
163
  data: event,
164
+ userActivity: isSessionActivityEvent(event),
163
165
  ...nextAdoptionMeta ?? {}
164
166
  };
165
167
  counter += 1;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@spotify-confidence/csr-common",
3
3
  "license": "Apache-2.0",
4
- "version": "0.18.8",
4
+ "version": "0.18.10",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/spotify/confidence-sdk-js.git",