@zaplier/sdk 1.2.5 → 1.2.7
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.cjs +154 -100
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +154 -100
- package/dist/index.esm.js.map +1 -1
- package/dist/sdk.js +154 -100
- package/dist/sdk.js.map +1 -1
- package/dist/sdk.min.js +1 -1
- package/dist/src/modules/session-replay.d.ts +1 -1
- package/dist/src/modules/session-replay.d.ts.map +1 -1
- package/dist/src/sdk.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6878,7 +6878,7 @@ class SessionReplayEngine {
|
|
|
6878
6878
|
const target = event.target;
|
|
6879
6879
|
const path = this.getElementPath(target);
|
|
6880
6880
|
this.addEvent({
|
|
6881
|
-
type:
|
|
6881
|
+
type: "click",
|
|
6882
6882
|
timestamp: Date.now(),
|
|
6883
6883
|
data: {
|
|
6884
6884
|
x: event.clientX,
|
|
@@ -6887,9 +6887,9 @@ class SessionReplayEngine {
|
|
|
6887
6887
|
button: event.button,
|
|
6888
6888
|
ctrlKey: event.ctrlKey,
|
|
6889
6889
|
shiftKey: event.shiftKey,
|
|
6890
|
-
altKey: event.altKey
|
|
6890
|
+
altKey: event.altKey,
|
|
6891
6891
|
},
|
|
6892
|
-
sequence: this.sequence
|
|
6892
|
+
sequence: this.sequence++,
|
|
6893
6893
|
});
|
|
6894
6894
|
};
|
|
6895
6895
|
/**
|
|
@@ -6897,13 +6897,13 @@ class SessionReplayEngine {
|
|
|
6897
6897
|
*/
|
|
6898
6898
|
this.handleScroll = () => {
|
|
6899
6899
|
this.addEvent({
|
|
6900
|
-
type:
|
|
6900
|
+
type: "scroll",
|
|
6901
6901
|
timestamp: Date.now(),
|
|
6902
6902
|
data: {
|
|
6903
6903
|
x: window.pageXOffset || document.documentElement.scrollLeft,
|
|
6904
|
-
y: window.pageYOffset || document.documentElement.scrollTop
|
|
6904
|
+
y: window.pageYOffset || document.documentElement.scrollTop,
|
|
6905
6905
|
},
|
|
6906
|
-
sequence: this.sequence
|
|
6906
|
+
sequence: this.sequence++,
|
|
6907
6907
|
});
|
|
6908
6908
|
};
|
|
6909
6909
|
/**
|
|
@@ -6915,17 +6915,17 @@ class SessionReplayEngine {
|
|
|
6915
6915
|
let value = target.value;
|
|
6916
6916
|
// Mask sensitive fields
|
|
6917
6917
|
if (this.config.maskSensitiveFields && this.isSensitiveField(target)) {
|
|
6918
|
-
value =
|
|
6918
|
+
value = "*".repeat(value.length);
|
|
6919
6919
|
}
|
|
6920
6920
|
this.addEvent({
|
|
6921
|
-
type:
|
|
6921
|
+
type: "input",
|
|
6922
6922
|
timestamp: Date.now(),
|
|
6923
6923
|
data: {
|
|
6924
6924
|
element: path,
|
|
6925
6925
|
value: value,
|
|
6926
|
-
inputType: event.inputType
|
|
6926
|
+
inputType: event.inputType,
|
|
6927
6927
|
},
|
|
6928
|
-
sequence: this.sequence
|
|
6928
|
+
sequence: this.sequence++,
|
|
6929
6929
|
});
|
|
6930
6930
|
};
|
|
6931
6931
|
/**
|
|
@@ -6936,17 +6936,17 @@ class SessionReplayEngine {
|
|
|
6936
6936
|
const path = this.getElementPath(target);
|
|
6937
6937
|
let value = target.value;
|
|
6938
6938
|
if (this.config.maskSensitiveFields && this.isSensitiveField(target)) {
|
|
6939
|
-
value =
|
|
6939
|
+
value = "*".repeat(value.length);
|
|
6940
6940
|
}
|
|
6941
6941
|
this.addEvent({
|
|
6942
|
-
type:
|
|
6942
|
+
type: "input",
|
|
6943
6943
|
timestamp: Date.now(),
|
|
6944
6944
|
data: {
|
|
6945
6945
|
element: path,
|
|
6946
6946
|
value: value,
|
|
6947
|
-
type:
|
|
6947
|
+
type: "change",
|
|
6948
6948
|
},
|
|
6949
|
-
sequence: this.sequence
|
|
6949
|
+
sequence: this.sequence++,
|
|
6950
6950
|
});
|
|
6951
6951
|
};
|
|
6952
6952
|
/**
|
|
@@ -6959,13 +6959,13 @@ class SessionReplayEngine {
|
|
|
6959
6959
|
}
|
|
6960
6960
|
this.lastMouseMove = now;
|
|
6961
6961
|
this.addEvent({
|
|
6962
|
-
type:
|
|
6962
|
+
type: "mouse",
|
|
6963
6963
|
timestamp: now,
|
|
6964
6964
|
data: {
|
|
6965
6965
|
x: event.clientX,
|
|
6966
|
-
y: event.clientY
|
|
6966
|
+
y: event.clientY,
|
|
6967
6967
|
},
|
|
6968
|
-
sequence: this.sequence
|
|
6968
|
+
sequence: this.sequence++,
|
|
6969
6969
|
});
|
|
6970
6970
|
};
|
|
6971
6971
|
/**
|
|
@@ -6973,13 +6973,13 @@ class SessionReplayEngine {
|
|
|
6973
6973
|
*/
|
|
6974
6974
|
this.handleViewportChange = () => {
|
|
6975
6975
|
this.addEvent({
|
|
6976
|
-
type:
|
|
6976
|
+
type: "viewport",
|
|
6977
6977
|
timestamp: Date.now(),
|
|
6978
6978
|
data: {
|
|
6979
6979
|
width: window.innerWidth,
|
|
6980
|
-
height: window.innerHeight
|
|
6980
|
+
height: window.innerHeight,
|
|
6981
6981
|
},
|
|
6982
|
-
sequence: this.sequence
|
|
6982
|
+
sequence: this.sequence++,
|
|
6983
6983
|
});
|
|
6984
6984
|
};
|
|
6985
6985
|
/**
|
|
@@ -7001,7 +7001,7 @@ class SessionReplayEngine {
|
|
|
7001
7001
|
captureInputs: true,
|
|
7002
7002
|
captureMouseMoves: false, // Disabled by default for performance
|
|
7003
7003
|
compressionEnabled: true,
|
|
7004
|
-
...config
|
|
7004
|
+
...config,
|
|
7005
7005
|
};
|
|
7006
7006
|
}
|
|
7007
7007
|
/**
|
|
@@ -7046,18 +7046,18 @@ class SessionReplayEngine {
|
|
|
7046
7046
|
* Setup DOM mutation observer
|
|
7047
7047
|
*/
|
|
7048
7048
|
setupDOMObserver() {
|
|
7049
|
-
if (typeof MutationObserver ===
|
|
7049
|
+
if (typeof MutationObserver === "undefined")
|
|
7050
7050
|
return;
|
|
7051
7051
|
this.observer = new MutationObserver((mutations) => {
|
|
7052
7052
|
const serializedMutations = mutations
|
|
7053
|
-
.map(mutation => this.serializeMutation(mutation))
|
|
7053
|
+
.map((mutation) => this.serializeMutation(mutation))
|
|
7054
7054
|
.filter(Boolean);
|
|
7055
7055
|
if (serializedMutations.length > 0) {
|
|
7056
7056
|
this.addEvent({
|
|
7057
|
-
type:
|
|
7057
|
+
type: "mutation",
|
|
7058
7058
|
timestamp: Date.now(),
|
|
7059
7059
|
data: { mutations: serializedMutations },
|
|
7060
|
-
sequence: this.sequence
|
|
7060
|
+
sequence: this.sequence++,
|
|
7061
7061
|
});
|
|
7062
7062
|
}
|
|
7063
7063
|
});
|
|
@@ -7067,7 +7067,7 @@ class SessionReplayEngine {
|
|
|
7067
7067
|
attributes: true,
|
|
7068
7068
|
attributeOldValue: true,
|
|
7069
7069
|
characterData: true,
|
|
7070
|
-
characterDataOldValue: true
|
|
7070
|
+
characterDataOldValue: true,
|
|
7071
7071
|
});
|
|
7072
7072
|
}
|
|
7073
7073
|
/**
|
|
@@ -7075,47 +7075,49 @@ class SessionReplayEngine {
|
|
|
7075
7075
|
*/
|
|
7076
7076
|
setupEventListeners() {
|
|
7077
7077
|
if (this.config.captureClicks) {
|
|
7078
|
-
document.addEventListener(
|
|
7078
|
+
document.addEventListener("click", this.handleClick, true);
|
|
7079
7079
|
}
|
|
7080
7080
|
if (this.config.captureScrolls) {
|
|
7081
|
-
window.addEventListener(
|
|
7082
|
-
document.addEventListener(
|
|
7081
|
+
window.addEventListener("scroll", this.handleScroll, { passive: true });
|
|
7082
|
+
document.addEventListener("scroll", this.handleScroll, { passive: true });
|
|
7083
7083
|
}
|
|
7084
7084
|
if (this.config.captureInputs) {
|
|
7085
|
-
document.addEventListener(
|
|
7086
|
-
document.addEventListener(
|
|
7085
|
+
document.addEventListener("input", this.handleInput, true);
|
|
7086
|
+
document.addEventListener("change", this.handleChange, true);
|
|
7087
7087
|
}
|
|
7088
7088
|
if (this.config.captureMouseMoves) {
|
|
7089
|
-
document.addEventListener(
|
|
7089
|
+
document.addEventListener("mousemove", this.handleMouseMove, {
|
|
7090
|
+
passive: true,
|
|
7091
|
+
});
|
|
7090
7092
|
}
|
|
7091
7093
|
// Viewport changes
|
|
7092
|
-
window.addEventListener(
|
|
7093
|
-
window.addEventListener(
|
|
7094
|
+
window.addEventListener("resize", this.handleViewportChange);
|
|
7095
|
+
window.addEventListener("orientationchange", this.handleViewportChange);
|
|
7094
7096
|
// Navigation
|
|
7095
|
-
window.addEventListener(
|
|
7096
|
-
window.addEventListener(
|
|
7097
|
+
window.addEventListener("beforeunload", this.handleNavigation);
|
|
7098
|
+
window.addEventListener("pagehide", this.handleNavigation);
|
|
7097
7099
|
}
|
|
7098
7100
|
/**
|
|
7099
7101
|
* Remove event listeners
|
|
7100
7102
|
*/
|
|
7101
7103
|
removeEventListeners() {
|
|
7102
|
-
document.removeEventListener(
|
|
7103
|
-
window.removeEventListener(
|
|
7104
|
-
document.removeEventListener(
|
|
7105
|
-
document.removeEventListener(
|
|
7106
|
-
document.removeEventListener(
|
|
7107
|
-
document.removeEventListener(
|
|
7108
|
-
window.removeEventListener(
|
|
7109
|
-
window.removeEventListener(
|
|
7110
|
-
window.removeEventListener(
|
|
7111
|
-
window.removeEventListener(
|
|
7104
|
+
document.removeEventListener("click", this.handleClick, true);
|
|
7105
|
+
window.removeEventListener("scroll", this.handleScroll);
|
|
7106
|
+
document.removeEventListener("scroll", this.handleScroll);
|
|
7107
|
+
document.removeEventListener("input", this.handleInput, true);
|
|
7108
|
+
document.removeEventListener("change", this.handleChange, true);
|
|
7109
|
+
document.removeEventListener("mousemove", this.handleMouseMove);
|
|
7110
|
+
window.removeEventListener("resize", this.handleViewportChange);
|
|
7111
|
+
window.removeEventListener("orientationchange", this.handleViewportChange);
|
|
7112
|
+
window.removeEventListener("beforeunload", this.handleNavigation);
|
|
7113
|
+
window.removeEventListener("pagehide", this.handleNavigation);
|
|
7112
7114
|
}
|
|
7113
7115
|
/**
|
|
7114
7116
|
* Record initial DOM state
|
|
7115
7117
|
*/
|
|
7116
7118
|
recordInitialState() {
|
|
7117
7119
|
this.addEvent({
|
|
7118
|
-
type:
|
|
7120
|
+
type: "navigation",
|
|
7119
7121
|
timestamp: Date.now(),
|
|
7120
7122
|
data: {
|
|
7121
7123
|
url: window.location.href,
|
|
@@ -7123,14 +7125,14 @@ class SessionReplayEngine {
|
|
|
7123
7125
|
title: document.title,
|
|
7124
7126
|
viewport: {
|
|
7125
7127
|
width: window.innerWidth,
|
|
7126
|
-
height: window.innerHeight
|
|
7128
|
+
height: window.innerHeight,
|
|
7127
7129
|
},
|
|
7128
7130
|
screen: {
|
|
7129
7131
|
width: window.screen?.width || 0,
|
|
7130
|
-
height: window.screen?.height || 0
|
|
7131
|
-
}
|
|
7132
|
+
height: window.screen?.height || 0,
|
|
7133
|
+
},
|
|
7132
7134
|
},
|
|
7133
|
-
sequence: this.sequence
|
|
7135
|
+
sequence: this.sequence++,
|
|
7134
7136
|
});
|
|
7135
7137
|
}
|
|
7136
7138
|
/**
|
|
@@ -7139,25 +7141,25 @@ class SessionReplayEngine {
|
|
|
7139
7141
|
serializeMutation(mutation) {
|
|
7140
7142
|
const result = {
|
|
7141
7143
|
type: mutation.type,
|
|
7142
|
-
target: this.getElementPath(mutation.target)
|
|
7144
|
+
target: this.getElementPath(mutation.target),
|
|
7143
7145
|
};
|
|
7144
7146
|
switch (mutation.type) {
|
|
7145
|
-
case
|
|
7147
|
+
case "childList":
|
|
7146
7148
|
result.addedNodes = Array.from(mutation.addedNodes)
|
|
7147
|
-
.filter(node => node.nodeType === Node.ELEMENT_NODE)
|
|
7148
|
-
.map(node => this.serializeElement(node))
|
|
7149
|
+
.filter((node) => node.nodeType === Node.ELEMENT_NODE)
|
|
7150
|
+
.map((node) => this.serializeElement(node))
|
|
7149
7151
|
.slice(0, 10); // Limit to prevent huge payloads
|
|
7150
7152
|
result.removedNodes = Array.from(mutation.removedNodes)
|
|
7151
|
-
.filter(node => node.nodeType === Node.ELEMENT_NODE)
|
|
7152
|
-
.map(node => this.getElementPath(node))
|
|
7153
|
+
.filter((node) => node.nodeType === Node.ELEMENT_NODE)
|
|
7154
|
+
.map((node) => this.getElementPath(node))
|
|
7153
7155
|
.slice(0, 10);
|
|
7154
7156
|
break;
|
|
7155
|
-
case
|
|
7157
|
+
case "attributes":
|
|
7156
7158
|
result.attributeName = mutation.attributeName;
|
|
7157
7159
|
result.oldValue = mutation.oldValue;
|
|
7158
7160
|
result.newValue = mutation.target.getAttribute(mutation.attributeName);
|
|
7159
7161
|
break;
|
|
7160
|
-
case
|
|
7162
|
+
case "characterData":
|
|
7161
7163
|
result.oldValue = mutation.oldValue;
|
|
7162
7164
|
result.newValue = mutation.target.textContent;
|
|
7163
7165
|
break;
|
|
@@ -7178,7 +7180,7 @@ class SessionReplayEngine {
|
|
|
7178
7180
|
return {
|
|
7179
7181
|
tagName: element.tagName.toLowerCase(),
|
|
7180
7182
|
attributes,
|
|
7181
|
-
textContent: element.textContent?.substring(0, 1000) ||
|
|
7183
|
+
textContent: element.textContent?.substring(0, 1000) || "", // Limit text content
|
|
7182
7184
|
};
|
|
7183
7185
|
}
|
|
7184
7186
|
/**
|
|
@@ -7196,7 +7198,7 @@ class SessionReplayEngine {
|
|
|
7196
7198
|
}
|
|
7197
7199
|
if (current.className) {
|
|
7198
7200
|
const classes = current.className.toString().split(/\s+/).slice(0, 2);
|
|
7199
|
-
selector += `.${classes.join(
|
|
7201
|
+
selector += `.${classes.join(".")}`;
|
|
7200
7202
|
}
|
|
7201
7203
|
// Add nth-child if no unique identifier
|
|
7202
7204
|
if (!current.id && !current.className) {
|
|
@@ -7207,26 +7209,38 @@ class SessionReplayEngine {
|
|
|
7207
7209
|
path.unshift(selector);
|
|
7208
7210
|
current = current.parentElement;
|
|
7209
7211
|
}
|
|
7210
|
-
return path.join(
|
|
7212
|
+
return path.join(" > ");
|
|
7211
7213
|
}
|
|
7212
7214
|
/**
|
|
7213
7215
|
* Check if field should be masked
|
|
7214
7216
|
*/
|
|
7215
7217
|
isSensitiveField(element) {
|
|
7216
|
-
const sensitiveTypes = [
|
|
7217
|
-
const sensitiveNames = [
|
|
7218
|
-
|
|
7219
|
-
|
|
7218
|
+
const sensitiveTypes = ["password", "email", "tel", "ssn", "cc"];
|
|
7219
|
+
const sensitiveNames = [
|
|
7220
|
+
"password",
|
|
7221
|
+
"email",
|
|
7222
|
+
"phone",
|
|
7223
|
+
"credit",
|
|
7224
|
+
"card",
|
|
7225
|
+
"ssn",
|
|
7226
|
+
"social",
|
|
7227
|
+
];
|
|
7228
|
+
const type = element.getAttribute("type")?.toLowerCase();
|
|
7229
|
+
const name = element.getAttribute("name")?.toLowerCase();
|
|
7220
7230
|
const className = element.className.toLowerCase();
|
|
7221
|
-
return sensitiveTypes.includes(type ||
|
|
7222
|
-
sensitiveNames.some(term => (name && name.includes(term)) ||
|
|
7223
|
-
className.includes(term));
|
|
7231
|
+
return (sensitiveTypes.includes(type || "") ||
|
|
7232
|
+
sensitiveNames.some((term) => (name && name.includes(term)) || className.includes(term)));
|
|
7224
7233
|
}
|
|
7225
7234
|
/**
|
|
7226
7235
|
* Check if attribute should be masked
|
|
7227
7236
|
*/
|
|
7228
7237
|
isSensitiveAttribute(attrName) {
|
|
7229
|
-
const sensitiveAttrs = [
|
|
7238
|
+
const sensitiveAttrs = [
|
|
7239
|
+
"data-token",
|
|
7240
|
+
"data-key",
|
|
7241
|
+
"data-secret",
|
|
7242
|
+
"authorization",
|
|
7243
|
+
];
|
|
7230
7244
|
return sensitiveAttrs.includes(attrName.toLowerCase());
|
|
7231
7245
|
}
|
|
7232
7246
|
/**
|
|
@@ -7251,18 +7265,21 @@ class SessionReplayEngine {
|
|
|
7251
7265
|
* Send batch of events
|
|
7252
7266
|
*/
|
|
7253
7267
|
sendBatch() {
|
|
7254
|
-
if (this.events.length === 0)
|
|
7268
|
+
if (this.events.length === 0) {
|
|
7269
|
+
console.log("[Zaplier] No events to send in batch");
|
|
7255
7270
|
return;
|
|
7271
|
+
}
|
|
7256
7272
|
const batch = [...this.events];
|
|
7257
7273
|
this.events = [];
|
|
7274
|
+
console.log(`[Zaplier] Sending batch with ${batch.length} events for session ${this.sessionId}`);
|
|
7258
7275
|
const payload = {
|
|
7259
7276
|
sessionId: this.sessionId,
|
|
7260
7277
|
events: batch,
|
|
7261
7278
|
metadata: {
|
|
7262
7279
|
userAgent: navigator.userAgent,
|
|
7263
7280
|
timestamp: Date.now(),
|
|
7264
|
-
compression: this.config.compressionEnabled
|
|
7265
|
-
}
|
|
7281
|
+
compression: this.config.compressionEnabled,
|
|
7282
|
+
},
|
|
7266
7283
|
};
|
|
7267
7284
|
// This will be handled by the anti-adblock manager
|
|
7268
7285
|
this.sendToBackend(payload);
|
|
@@ -7280,39 +7297,55 @@ class SessionReplayEngine {
|
|
|
7280
7297
|
try {
|
|
7281
7298
|
// Try WebRTC first if anti-adblock manager is available
|
|
7282
7299
|
if (this.antiAdblockManager) {
|
|
7283
|
-
|
|
7300
|
+
console.log("[Zaplier] Trying WebRTC transport...");
|
|
7301
|
+
const result = await this.antiAdblockManager.send(payload, "/replays/record");
|
|
7284
7302
|
if (result.success) {
|
|
7303
|
+
console.log("[Zaplier] Session replay sent via WebRTC");
|
|
7285
7304
|
return; // Success via WebRTC
|
|
7286
7305
|
}
|
|
7306
|
+
console.log("[Zaplier] WebRTC failed, falling back to fetch");
|
|
7287
7307
|
}
|
|
7288
7308
|
// Get API endpoint from global config
|
|
7289
|
-
const apiEndpoint = window.zaplier_config?.apiEndpoint ||
|
|
7290
|
-
const token = window.zaplier_config?.token ||
|
|
7309
|
+
const apiEndpoint = window.zaplier_config?.apiEndpoint || "http://localhost:3001";
|
|
7310
|
+
const token = window.zaplier_config?.token || "ws_demo_token";
|
|
7311
|
+
const url = `${apiEndpoint}/replays/record?token=${token}`;
|
|
7312
|
+
console.log(`[Zaplier] Sending replay batch to ${url}`);
|
|
7313
|
+
console.log(`[Zaplier] Payload:`, {
|
|
7314
|
+
sessionId: payload.sessionId,
|
|
7315
|
+
eventCount: payload.events.length,
|
|
7316
|
+
hasMetadata: !!payload.metadata,
|
|
7317
|
+
});
|
|
7318
|
+
const requestBody = {
|
|
7319
|
+
sessionId: payload.sessionId,
|
|
7320
|
+
events: payload.events,
|
|
7321
|
+
metadata: {
|
|
7322
|
+
startUrl: window.location.href,
|
|
7323
|
+
duration: Date.now() - (performance.timeOrigin || Date.now()),
|
|
7324
|
+
funnelSteps: [],
|
|
7325
|
+
hasConversion: false,
|
|
7326
|
+
...payload.metadata,
|
|
7327
|
+
},
|
|
7328
|
+
};
|
|
7291
7329
|
// Fallback to standard fetch
|
|
7292
|
-
const response = await fetch(
|
|
7293
|
-
method:
|
|
7294
|
-
headers: {
|
|
7295
|
-
body: JSON.stringify(
|
|
7296
|
-
sessionId: payload.sessionId,
|
|
7297
|
-
events: payload.events,
|
|
7298
|
-
metadata: {
|
|
7299
|
-
startUrl: window.location.href,
|
|
7300
|
-
duration: Date.now() - (performance.timeOrigin || Date.now()),
|
|
7301
|
-
funnelSteps: [],
|
|
7302
|
-
hasConversion: false,
|
|
7303
|
-
...payload.metadata
|
|
7304
|
-
}
|
|
7305
|
-
})
|
|
7330
|
+
const response = await fetch(url, {
|
|
7331
|
+
method: "POST",
|
|
7332
|
+
headers: { "Content-Type": "application/json" },
|
|
7333
|
+
body: JSON.stringify(requestBody),
|
|
7306
7334
|
});
|
|
7335
|
+
const responseText = await response.text();
|
|
7307
7336
|
if (!response.ok) {
|
|
7308
|
-
console.
|
|
7337
|
+
console.error("[Zaplier] Session replay batch failed:", {
|
|
7338
|
+
status: response.status,
|
|
7339
|
+
statusText: response.statusText,
|
|
7340
|
+
response: responseText,
|
|
7341
|
+
});
|
|
7309
7342
|
}
|
|
7310
7343
|
else {
|
|
7311
|
-
console.log(
|
|
7344
|
+
console.log("[Zaplier] Session replay batch sent successfully:", responseText);
|
|
7312
7345
|
}
|
|
7313
7346
|
}
|
|
7314
7347
|
catch (error) {
|
|
7315
|
-
console.
|
|
7348
|
+
console.error("[Zaplier] Session replay error:", error);
|
|
7316
7349
|
}
|
|
7317
7350
|
}
|
|
7318
7351
|
/**
|
|
@@ -7430,8 +7463,9 @@ class ZaplierSDK {
|
|
|
7430
7463
|
this.sessionId = this.generateSessionId();
|
|
7431
7464
|
}
|
|
7432
7465
|
const sessionId = this.sessionId;
|
|
7466
|
+
// When explicitly enabled, use 100% sample rate
|
|
7433
7467
|
this.replayEngine = new SessionReplayEngine(sessionId, {
|
|
7434
|
-
sampleRate:
|
|
7468
|
+
sampleRate: 1.0, // Force 100% when explicitly enabled
|
|
7435
7469
|
maskSensitiveFields: this.config.replayMaskInputs,
|
|
7436
7470
|
compressionEnabled: true,
|
|
7437
7471
|
});
|
|
@@ -7439,10 +7473,23 @@ class ZaplierSDK {
|
|
|
7439
7473
|
if (this.antiAdblockManager) {
|
|
7440
7474
|
this.replayEngine.setAntiAdblockManager(this.antiAdblockManager);
|
|
7441
7475
|
}
|
|
7442
|
-
this.replayEngine.start();
|
|
7476
|
+
const started = this.replayEngine.start();
|
|
7477
|
+
if (this.config.debug) {
|
|
7478
|
+
console.log("[Zaplier] Replay enabled", {
|
|
7479
|
+
started,
|
|
7480
|
+
isRecording: this.replayEngine.isRecording(),
|
|
7481
|
+
});
|
|
7482
|
+
}
|
|
7443
7483
|
}
|
|
7444
|
-
if (this.
|
|
7445
|
-
|
|
7484
|
+
else if (this.replayEngine) {
|
|
7485
|
+
// If engine already exists, try to start it (might have failed due to sampling before)
|
|
7486
|
+
const started = this.replayEngine.start();
|
|
7487
|
+
if (this.config.debug) {
|
|
7488
|
+
console.log("[Zaplier] Replay engine already exists, attempting start", { started });
|
|
7489
|
+
}
|
|
7490
|
+
}
|
|
7491
|
+
if (this.config.debug && !this.replayEngine) {
|
|
7492
|
+
console.log("[Zaplier] Replay enabled (will start when SDK initializes)");
|
|
7446
7493
|
}
|
|
7447
7494
|
},
|
|
7448
7495
|
disable: () => {
|
|
@@ -7565,8 +7612,11 @@ class ZaplierSDK {
|
|
|
7565
7612
|
}
|
|
7566
7613
|
// Initialize Session Replay Engine
|
|
7567
7614
|
if (this.config.replay) {
|
|
7615
|
+
// When replay is explicitly enabled, use 100% sample rate to ensure recording
|
|
7616
|
+
// The default replaySampling (0.1) is only for automatic/production sampling
|
|
7617
|
+
const sampleRate = this.config.replay === true ? 1.0 : this.config.replaySampling;
|
|
7568
7618
|
this.replayEngine = new SessionReplayEngine(this.sessionId, {
|
|
7569
|
-
sampleRate:
|
|
7619
|
+
sampleRate: sampleRate,
|
|
7570
7620
|
maskSensitiveFields: this.config.replayMaskInputs,
|
|
7571
7621
|
compressionEnabled: true,
|
|
7572
7622
|
});
|
|
@@ -7574,9 +7624,13 @@ class ZaplierSDK {
|
|
|
7574
7624
|
if (this.antiAdblockManager) {
|
|
7575
7625
|
this.replayEngine.setAntiAdblockManager(this.antiAdblockManager);
|
|
7576
7626
|
}
|
|
7577
|
-
this.replayEngine.start();
|
|
7627
|
+
const started = this.replayEngine.start();
|
|
7578
7628
|
if (this.config.debug) {
|
|
7579
|
-
console.log("[Zaplier] Session Replay started"
|
|
7629
|
+
console.log("[Zaplier] Session Replay started", {
|
|
7630
|
+
started,
|
|
7631
|
+
sampleRate,
|
|
7632
|
+
isRecording: this.replayEngine.isRecording(),
|
|
7633
|
+
});
|
|
7580
7634
|
}
|
|
7581
7635
|
}
|
|
7582
7636
|
// Initialize Heatmap Engine
|