@spotify-confidence/session-recording 0.18.10 → 0.18.11

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 CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## [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
+
5
+
6
+ ### Dependencies
7
+
8
+ * The following workspace dependencies were updated
9
+ * dependencies
10
+ * @spotify-confidence/csr-common bumped to 0.18.8
11
+ * @spotify-confidence/csr-recorder bumped to 0.17.16
12
+
3
13
  ## [0.18.10](https://github.com/spotify/confidence-sdk-js/compare/session-recording-v0.18.9...session-recording-v0.18.10) (2026-08-20)
4
14
 
5
15
 
package/dist/index.cjs CHANGED
@@ -21,7 +21,7 @@ function validateMeasureValue(value) {
21
21
  //#endregion
22
22
  //#region ../csr-recorder/src/types.ts
23
23
  const DEFAULT_MASK_SELECTORS = ["[data-csr-mask]"];
24
- const DEFAULT_BLOCK_SELECTORS = ["[data-csr-block]"];
24
+ const DEFAULT_BLOCK_SELECTORS = ["[data-csr-block]", "video"];
25
25
  //#endregion
26
26
  //#region ../csr-recorder/src/route-parameterizer.ts
27
27
  const SEGMENT_PATTERNS = [
@@ -11138,6 +11138,63 @@ const ALL_CONSOLE_LEVELS = [
11138
11138
  "debug",
11139
11139
  "info"
11140
11140
  ];
11141
+ const BLOCKED_ELEMENT_ATTRIBUTE = "data-csr-blocked-element";
11142
+ function labelBlockedElement(node) {
11143
+ if (node.type === 2 && node.tagName !== void 0 && node.attributes !== void 0 && typeof node.attributes.rr_width === "string" && typeof node.attributes.rr_height === "string") {
11144
+ node.attributes[BLOCKED_ELEMENT_ATTRIBUTE] = node.tagName;
11145
+ node.tagName = "div";
11146
+ }
11147
+ node.childNodes?.forEach(labelBlockedElement);
11148
+ }
11149
+ /**
11150
+ * rrweb strips blocked elements down to their dimensions, but retains their
11151
+ * original tag name. Rebuild them as inert divs and keep the tag name as safe
11152
+ * metadata so players can render a useful placeholder label.
11153
+ */
11154
+ function blockedElementLabelsPlugin() {
11155
+ return {
11156
+ name: "csr/blocked-element-labels@1",
11157
+ options: {},
11158
+ observer: () => () => {},
11159
+ eventProcessor: (event) => {
11160
+ if (event.type === EventType.FullSnapshot) labelBlockedElement(event.data.node);
11161
+ else if (event.type === EventType.IncrementalSnapshot && event.data.source === IncrementalSource.Mutation) event.data.adds.forEach((add) => labelBlockedElement(add.node));
11162
+ return event;
11163
+ }
11164
+ };
11165
+ }
11166
+ /**
11167
+ * Record clipboard actions and their DOM target without reading clipboard
11168
+ * contents. The resulting rrweb Plugin events can explain otherwise
11169
+ * surprising input changes during analysis.
11170
+ */
11171
+ function clipboardActionsPlugin() {
11172
+ let getId;
11173
+ return {
11174
+ name: "csr/clipboard@1",
11175
+ options: {},
11176
+ getMirror: ({ nodeMirror }) => {
11177
+ getId = (node) => nodeMirror.getId(node);
11178
+ },
11179
+ observer: (callback, win) => {
11180
+ const handlers = [
11181
+ "copy",
11182
+ "cut",
11183
+ "paste"
11184
+ ].map((action) => {
11185
+ const handler = (event) => {
11186
+ callback({
11187
+ action,
11188
+ targetId: event.target instanceof win.Node ? getId?.(event.target) ?? -1 : -1
11189
+ });
11190
+ };
11191
+ win.document.addEventListener(action, handler, true);
11192
+ return () => win.document.removeEventListener(action, handler, true);
11193
+ });
11194
+ return () => handlers.forEach((remove) => remove());
11195
+ }
11196
+ };
11197
+ }
11141
11198
  /**
11142
11199
  * rrweb does not include modifier keys in mouse-interaction events. Capture
11143
11200
  * the native click first, then add its safe, non-text metadata to the rrweb
@@ -11190,7 +11247,11 @@ var RrwebEngine = class {
11190
11247
  start(config, onEvent) {
11191
11248
  const maskSelectors = config.maskSelectors ?? DEFAULT_MASK_SELECTORS;
11192
11249
  const blockSelectors = config.blockSelectors ?? DEFAULT_BLOCK_SELECTORS;
11193
- const plugins = [clickModifiersPlugin()];
11250
+ const plugins = [
11251
+ clickModifiersPlugin(),
11252
+ clipboardActionsPlugin(),
11253
+ blockedElementLabelsPlugin()
11254
+ ];
11194
11255
  const { captureConsoleLogs } = config;
11195
11256
  if (captureConsoleLogs) {
11196
11257
  const levels = captureConsoleLogs === true ? ALL_CONSOLE_LEVELS : captureConsoleLogs.levels;
@@ -11265,7 +11326,7 @@ function observeFlags(onFlagWrite) {
11265
11326
  }
11266
11327
  //#endregion
11267
11328
  //#region src/version.ts
11268
- const SDK_VERSION = "0.18.10";
11329
+ const SDK_VERSION = "0.18.11";
11269
11330
  //#endregion
11270
11331
  //#region src/index.ts
11271
11332
  const DEFAULT_API_URL = "https://recording.confidence.dev";
package/dist/index.js CHANGED
@@ -20,7 +20,7 @@ function validateMeasureValue(value) {
20
20
  //#endregion
21
21
  //#region ../csr-recorder/src/types.ts
22
22
  const DEFAULT_MASK_SELECTORS = ["[data-csr-mask]"];
23
- const DEFAULT_BLOCK_SELECTORS = ["[data-csr-block]"];
23
+ const DEFAULT_BLOCK_SELECTORS = ["[data-csr-block]", "video"];
24
24
  //#endregion
25
25
  //#region ../csr-recorder/src/route-parameterizer.ts
26
26
  const SEGMENT_PATTERNS = [
@@ -11119,6 +11119,63 @@ const ALL_CONSOLE_LEVELS = [
11119
11119
  "debug",
11120
11120
  "info"
11121
11121
  ];
11122
+ const BLOCKED_ELEMENT_ATTRIBUTE = "data-csr-blocked-element";
11123
+ function labelBlockedElement(node) {
11124
+ if (node.type === 2 && node.tagName !== void 0 && node.attributes !== void 0 && typeof node.attributes.rr_width === "string" && typeof node.attributes.rr_height === "string") {
11125
+ node.attributes[BLOCKED_ELEMENT_ATTRIBUTE] = node.tagName;
11126
+ node.tagName = "div";
11127
+ }
11128
+ node.childNodes?.forEach(labelBlockedElement);
11129
+ }
11130
+ /**
11131
+ * rrweb strips blocked elements down to their dimensions, but retains their
11132
+ * original tag name. Rebuild them as inert divs and keep the tag name as safe
11133
+ * metadata so players can render a useful placeholder label.
11134
+ */
11135
+ function blockedElementLabelsPlugin() {
11136
+ return {
11137
+ name: "csr/blocked-element-labels@1",
11138
+ options: {},
11139
+ observer: () => () => {},
11140
+ eventProcessor: (event) => {
11141
+ if (event.type === EventType.FullSnapshot) labelBlockedElement(event.data.node);
11142
+ else if (event.type === EventType.IncrementalSnapshot && event.data.source === IncrementalSource.Mutation) event.data.adds.forEach((add) => labelBlockedElement(add.node));
11143
+ return event;
11144
+ }
11145
+ };
11146
+ }
11147
+ /**
11148
+ * Record clipboard actions and their DOM target without reading clipboard
11149
+ * contents. The resulting rrweb Plugin events can explain otherwise
11150
+ * surprising input changes during analysis.
11151
+ */
11152
+ function clipboardActionsPlugin() {
11153
+ let getId;
11154
+ return {
11155
+ name: "csr/clipboard@1",
11156
+ options: {},
11157
+ getMirror: ({ nodeMirror }) => {
11158
+ getId = (node) => nodeMirror.getId(node);
11159
+ },
11160
+ observer: (callback, win) => {
11161
+ const handlers = [
11162
+ "copy",
11163
+ "cut",
11164
+ "paste"
11165
+ ].map((action) => {
11166
+ const handler = (event) => {
11167
+ callback({
11168
+ action,
11169
+ targetId: event.target instanceof win.Node ? getId?.(event.target) ?? -1 : -1
11170
+ });
11171
+ };
11172
+ win.document.addEventListener(action, handler, true);
11173
+ return () => win.document.removeEventListener(action, handler, true);
11174
+ });
11175
+ return () => handlers.forEach((remove) => remove());
11176
+ }
11177
+ };
11178
+ }
11122
11179
  /**
11123
11180
  * rrweb does not include modifier keys in mouse-interaction events. Capture
11124
11181
  * the native click first, then add its safe, non-text metadata to the rrweb
@@ -11171,7 +11228,11 @@ var RrwebEngine = class {
11171
11228
  start(config, onEvent) {
11172
11229
  const maskSelectors = config.maskSelectors ?? DEFAULT_MASK_SELECTORS;
11173
11230
  const blockSelectors = config.blockSelectors ?? DEFAULT_BLOCK_SELECTORS;
11174
- const plugins = [clickModifiersPlugin()];
11231
+ const plugins = [
11232
+ clickModifiersPlugin(),
11233
+ clipboardActionsPlugin(),
11234
+ blockedElementLabelsPlugin()
11235
+ ];
11175
11236
  const { captureConsoleLogs } = config;
11176
11237
  if (captureConsoleLogs) {
11177
11238
  const levels = captureConsoleLogs === true ? ALL_CONSOLE_LEVELS : captureConsoleLogs.levels;
@@ -11246,7 +11307,7 @@ function observeFlags(onFlagWrite) {
11246
11307
  }
11247
11308
  //#endregion
11248
11309
  //#region src/version.ts
11249
- const SDK_VERSION = "0.18.10";
11310
+ const SDK_VERSION = "0.18.11";
11250
11311
  //#endregion
11251
11312
  //#region src/index.ts
11252
11313
  const DEFAULT_API_URL = "https://recording.confidence.dev";
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.10",
4
+ "version": "0.18.11",
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.7",
45
- "@spotify-confidence/csr-recorder": "0.17.15"
44
+ "@spotify-confidence/csr-common": "0.18.8",
45
+ "@spotify-confidence/csr-recorder": "0.17.16"
46
46
  },
47
47
  "module": "./dist/index.js",
48
48
  "exports": {
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const SDK_VERSION = '0.18.10';
1
+ export const SDK_VERSION = '0.18.11';