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