@zaplier/sdk 1.2.6 → 1.3.0
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 +202 -124
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.esm.js +202 -124
- package/dist/index.esm.js.map +1 -1
- package/dist/sdk.js +202 -124
- package/dist/sdk.js.map +1 -1
- package/dist/sdk.min.js +1 -1
- package/dist/src/modules/session-replay.d.ts +5 -5
- package/dist/src/modules/session-replay.d.ts.map +1 -1
- package/dist/src/sdk.d.ts +8 -0
- package/dist/src/sdk.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/sdk.js
CHANGED
|
@@ -6880,7 +6880,7 @@
|
|
|
6880
6880
|
const target = event.target;
|
|
6881
6881
|
const path = this.getElementPath(target);
|
|
6882
6882
|
this.addEvent({
|
|
6883
|
-
type:
|
|
6883
|
+
type: "click",
|
|
6884
6884
|
timestamp: Date.now(),
|
|
6885
6885
|
data: {
|
|
6886
6886
|
x: event.clientX,
|
|
@@ -6889,9 +6889,9 @@
|
|
|
6889
6889
|
button: event.button,
|
|
6890
6890
|
ctrlKey: event.ctrlKey,
|
|
6891
6891
|
shiftKey: event.shiftKey,
|
|
6892
|
-
altKey: event.altKey
|
|
6892
|
+
altKey: event.altKey,
|
|
6893
6893
|
},
|
|
6894
|
-
sequence: this.sequence
|
|
6894
|
+
sequence: this.sequence++,
|
|
6895
6895
|
});
|
|
6896
6896
|
};
|
|
6897
6897
|
/**
|
|
@@ -6899,13 +6899,13 @@
|
|
|
6899
6899
|
*/
|
|
6900
6900
|
this.handleScroll = () => {
|
|
6901
6901
|
this.addEvent({
|
|
6902
|
-
type:
|
|
6902
|
+
type: "scroll",
|
|
6903
6903
|
timestamp: Date.now(),
|
|
6904
6904
|
data: {
|
|
6905
6905
|
x: window.pageXOffset || document.documentElement.scrollLeft,
|
|
6906
|
-
y: window.pageYOffset || document.documentElement.scrollTop
|
|
6906
|
+
y: window.pageYOffset || document.documentElement.scrollTop,
|
|
6907
6907
|
},
|
|
6908
|
-
sequence: this.sequence
|
|
6908
|
+
sequence: this.sequence++,
|
|
6909
6909
|
});
|
|
6910
6910
|
};
|
|
6911
6911
|
/**
|
|
@@ -6917,17 +6917,17 @@
|
|
|
6917
6917
|
let value = target.value;
|
|
6918
6918
|
// Mask sensitive fields
|
|
6919
6919
|
if (this.config.maskSensitiveFields && this.isSensitiveField(target)) {
|
|
6920
|
-
value =
|
|
6920
|
+
value = "*".repeat(value.length);
|
|
6921
6921
|
}
|
|
6922
6922
|
this.addEvent({
|
|
6923
|
-
type:
|
|
6923
|
+
type: "input",
|
|
6924
6924
|
timestamp: Date.now(),
|
|
6925
6925
|
data: {
|
|
6926
6926
|
element: path,
|
|
6927
6927
|
value: value,
|
|
6928
|
-
inputType: event.inputType
|
|
6928
|
+
inputType: event.inputType,
|
|
6929
6929
|
},
|
|
6930
|
-
sequence: this.sequence
|
|
6930
|
+
sequence: this.sequence++,
|
|
6931
6931
|
});
|
|
6932
6932
|
};
|
|
6933
6933
|
/**
|
|
@@ -6938,17 +6938,17 @@
|
|
|
6938
6938
|
const path = this.getElementPath(target);
|
|
6939
6939
|
let value = target.value;
|
|
6940
6940
|
if (this.config.maskSensitiveFields && this.isSensitiveField(target)) {
|
|
6941
|
-
value =
|
|
6941
|
+
value = "*".repeat(value.length);
|
|
6942
6942
|
}
|
|
6943
6943
|
this.addEvent({
|
|
6944
|
-
type:
|
|
6944
|
+
type: "input",
|
|
6945
6945
|
timestamp: Date.now(),
|
|
6946
6946
|
data: {
|
|
6947
6947
|
element: path,
|
|
6948
6948
|
value: value,
|
|
6949
|
-
type:
|
|
6949
|
+
type: "change",
|
|
6950
6950
|
},
|
|
6951
|
-
sequence: this.sequence
|
|
6951
|
+
sequence: this.sequence++,
|
|
6952
6952
|
});
|
|
6953
6953
|
};
|
|
6954
6954
|
/**
|
|
@@ -6961,13 +6961,13 @@
|
|
|
6961
6961
|
}
|
|
6962
6962
|
this.lastMouseMove = now;
|
|
6963
6963
|
this.addEvent({
|
|
6964
|
-
type:
|
|
6964
|
+
type: "mouse",
|
|
6965
6965
|
timestamp: now,
|
|
6966
6966
|
data: {
|
|
6967
6967
|
x: event.clientX,
|
|
6968
|
-
y: event.clientY
|
|
6968
|
+
y: event.clientY,
|
|
6969
6969
|
},
|
|
6970
|
-
sequence: this.sequence
|
|
6970
|
+
sequence: this.sequence++,
|
|
6971
6971
|
});
|
|
6972
6972
|
};
|
|
6973
6973
|
/**
|
|
@@ -6975,13 +6975,13 @@
|
|
|
6975
6975
|
*/
|
|
6976
6976
|
this.handleViewportChange = () => {
|
|
6977
6977
|
this.addEvent({
|
|
6978
|
-
type:
|
|
6978
|
+
type: "viewport",
|
|
6979
6979
|
timestamp: Date.now(),
|
|
6980
6980
|
data: {
|
|
6981
6981
|
width: window.innerWidth,
|
|
6982
|
-
height: window.innerHeight
|
|
6982
|
+
height: window.innerHeight,
|
|
6983
6983
|
},
|
|
6984
|
-
sequence: this.sequence
|
|
6984
|
+
sequence: this.sequence++,
|
|
6985
6985
|
});
|
|
6986
6986
|
};
|
|
6987
6987
|
/**
|
|
@@ -7003,7 +7003,7 @@
|
|
|
7003
7003
|
captureInputs: true,
|
|
7004
7004
|
captureMouseMoves: false, // Disabled by default for performance
|
|
7005
7005
|
compressionEnabled: true,
|
|
7006
|
-
...config
|
|
7006
|
+
...config,
|
|
7007
7007
|
};
|
|
7008
7008
|
}
|
|
7009
7009
|
/**
|
|
@@ -7048,18 +7048,18 @@
|
|
|
7048
7048
|
* Setup DOM mutation observer
|
|
7049
7049
|
*/
|
|
7050
7050
|
setupDOMObserver() {
|
|
7051
|
-
if (typeof MutationObserver ===
|
|
7051
|
+
if (typeof MutationObserver === "undefined")
|
|
7052
7052
|
return;
|
|
7053
7053
|
this.observer = new MutationObserver((mutations) => {
|
|
7054
7054
|
const serializedMutations = mutations
|
|
7055
|
-
.map(mutation => this.serializeMutation(mutation))
|
|
7055
|
+
.map((mutation) => this.serializeMutation(mutation))
|
|
7056
7056
|
.filter(Boolean);
|
|
7057
7057
|
if (serializedMutations.length > 0) {
|
|
7058
7058
|
this.addEvent({
|
|
7059
|
-
type:
|
|
7059
|
+
type: "mutation",
|
|
7060
7060
|
timestamp: Date.now(),
|
|
7061
7061
|
data: { mutations: serializedMutations },
|
|
7062
|
-
sequence: this.sequence
|
|
7062
|
+
sequence: this.sequence++,
|
|
7063
7063
|
});
|
|
7064
7064
|
}
|
|
7065
7065
|
});
|
|
@@ -7069,7 +7069,7 @@
|
|
|
7069
7069
|
attributes: true,
|
|
7070
7070
|
attributeOldValue: true,
|
|
7071
7071
|
characterData: true,
|
|
7072
|
-
characterDataOldValue: true
|
|
7072
|
+
characterDataOldValue: true,
|
|
7073
7073
|
});
|
|
7074
7074
|
}
|
|
7075
7075
|
/**
|
|
@@ -7077,47 +7077,49 @@
|
|
|
7077
7077
|
*/
|
|
7078
7078
|
setupEventListeners() {
|
|
7079
7079
|
if (this.config.captureClicks) {
|
|
7080
|
-
document.addEventListener(
|
|
7080
|
+
document.addEventListener("click", this.handleClick, true);
|
|
7081
7081
|
}
|
|
7082
7082
|
if (this.config.captureScrolls) {
|
|
7083
|
-
window.addEventListener(
|
|
7084
|
-
document.addEventListener(
|
|
7083
|
+
window.addEventListener("scroll", this.handleScroll, { passive: true });
|
|
7084
|
+
document.addEventListener("scroll", this.handleScroll, { passive: true });
|
|
7085
7085
|
}
|
|
7086
7086
|
if (this.config.captureInputs) {
|
|
7087
|
-
document.addEventListener(
|
|
7088
|
-
document.addEventListener(
|
|
7087
|
+
document.addEventListener("input", this.handleInput, true);
|
|
7088
|
+
document.addEventListener("change", this.handleChange, true);
|
|
7089
7089
|
}
|
|
7090
7090
|
if (this.config.captureMouseMoves) {
|
|
7091
|
-
document.addEventListener(
|
|
7091
|
+
document.addEventListener("mousemove", this.handleMouseMove, {
|
|
7092
|
+
passive: true,
|
|
7093
|
+
});
|
|
7092
7094
|
}
|
|
7093
7095
|
// Viewport changes
|
|
7094
|
-
window.addEventListener(
|
|
7095
|
-
window.addEventListener(
|
|
7096
|
+
window.addEventListener("resize", this.handleViewportChange);
|
|
7097
|
+
window.addEventListener("orientationchange", this.handleViewportChange);
|
|
7096
7098
|
// Navigation
|
|
7097
|
-
window.addEventListener(
|
|
7098
|
-
window.addEventListener(
|
|
7099
|
+
window.addEventListener("beforeunload", this.handleNavigation);
|
|
7100
|
+
window.addEventListener("pagehide", this.handleNavigation);
|
|
7099
7101
|
}
|
|
7100
7102
|
/**
|
|
7101
7103
|
* Remove event listeners
|
|
7102
7104
|
*/
|
|
7103
7105
|
removeEventListeners() {
|
|
7104
|
-
document.removeEventListener(
|
|
7105
|
-
window.removeEventListener(
|
|
7106
|
-
document.removeEventListener(
|
|
7107
|
-
document.removeEventListener(
|
|
7108
|
-
document.removeEventListener(
|
|
7109
|
-
document.removeEventListener(
|
|
7110
|
-
window.removeEventListener(
|
|
7111
|
-
window.removeEventListener(
|
|
7112
|
-
window.removeEventListener(
|
|
7113
|
-
window.removeEventListener(
|
|
7106
|
+
document.removeEventListener("click", this.handleClick, true);
|
|
7107
|
+
window.removeEventListener("scroll", this.handleScroll);
|
|
7108
|
+
document.removeEventListener("scroll", this.handleScroll);
|
|
7109
|
+
document.removeEventListener("input", this.handleInput, true);
|
|
7110
|
+
document.removeEventListener("change", this.handleChange, true);
|
|
7111
|
+
document.removeEventListener("mousemove", this.handleMouseMove);
|
|
7112
|
+
window.removeEventListener("resize", this.handleViewportChange);
|
|
7113
|
+
window.removeEventListener("orientationchange", this.handleViewportChange);
|
|
7114
|
+
window.removeEventListener("beforeunload", this.handleNavigation);
|
|
7115
|
+
window.removeEventListener("pagehide", this.handleNavigation);
|
|
7114
7116
|
}
|
|
7115
7117
|
/**
|
|
7116
7118
|
* Record initial DOM state
|
|
7117
7119
|
*/
|
|
7118
7120
|
recordInitialState() {
|
|
7119
7121
|
this.addEvent({
|
|
7120
|
-
type:
|
|
7122
|
+
type: "navigation",
|
|
7121
7123
|
timestamp: Date.now(),
|
|
7122
7124
|
data: {
|
|
7123
7125
|
url: window.location.href,
|
|
@@ -7125,14 +7127,14 @@
|
|
|
7125
7127
|
title: document.title,
|
|
7126
7128
|
viewport: {
|
|
7127
7129
|
width: window.innerWidth,
|
|
7128
|
-
height: window.innerHeight
|
|
7130
|
+
height: window.innerHeight,
|
|
7129
7131
|
},
|
|
7130
7132
|
screen: {
|
|
7131
7133
|
width: window.screen?.width || 0,
|
|
7132
|
-
height: window.screen?.height || 0
|
|
7133
|
-
}
|
|
7134
|
+
height: window.screen?.height || 0,
|
|
7135
|
+
},
|
|
7134
7136
|
},
|
|
7135
|
-
sequence: this.sequence
|
|
7137
|
+
sequence: this.sequence++,
|
|
7136
7138
|
});
|
|
7137
7139
|
}
|
|
7138
7140
|
/**
|
|
@@ -7141,25 +7143,25 @@
|
|
|
7141
7143
|
serializeMutation(mutation) {
|
|
7142
7144
|
const result = {
|
|
7143
7145
|
type: mutation.type,
|
|
7144
|
-
target: this.getElementPath(mutation.target)
|
|
7146
|
+
target: this.getElementPath(mutation.target),
|
|
7145
7147
|
};
|
|
7146
7148
|
switch (mutation.type) {
|
|
7147
|
-
case
|
|
7149
|
+
case "childList":
|
|
7148
7150
|
result.addedNodes = Array.from(mutation.addedNodes)
|
|
7149
|
-
.filter(node => node.nodeType === Node.ELEMENT_NODE)
|
|
7150
|
-
.map(node => this.serializeElement(node))
|
|
7151
|
+
.filter((node) => node.nodeType === Node.ELEMENT_NODE)
|
|
7152
|
+
.map((node) => this.serializeElement(node))
|
|
7151
7153
|
.slice(0, 10); // Limit to prevent huge payloads
|
|
7152
7154
|
result.removedNodes = Array.from(mutation.removedNodes)
|
|
7153
|
-
.filter(node => node.nodeType === Node.ELEMENT_NODE)
|
|
7154
|
-
.map(node => this.getElementPath(node))
|
|
7155
|
+
.filter((node) => node.nodeType === Node.ELEMENT_NODE)
|
|
7156
|
+
.map((node) => this.getElementPath(node))
|
|
7155
7157
|
.slice(0, 10);
|
|
7156
7158
|
break;
|
|
7157
|
-
case
|
|
7159
|
+
case "attributes":
|
|
7158
7160
|
result.attributeName = mutation.attributeName;
|
|
7159
7161
|
result.oldValue = mutation.oldValue;
|
|
7160
7162
|
result.newValue = mutation.target.getAttribute(mutation.attributeName);
|
|
7161
7163
|
break;
|
|
7162
|
-
case
|
|
7164
|
+
case "characterData":
|
|
7163
7165
|
result.oldValue = mutation.oldValue;
|
|
7164
7166
|
result.newValue = mutation.target.textContent;
|
|
7165
7167
|
break;
|
|
@@ -7180,7 +7182,7 @@
|
|
|
7180
7182
|
return {
|
|
7181
7183
|
tagName: element.tagName.toLowerCase(),
|
|
7182
7184
|
attributes,
|
|
7183
|
-
textContent: element.textContent?.substring(0, 1000) ||
|
|
7185
|
+
textContent: element.textContent?.substring(0, 1000) || "", // Limit text content
|
|
7184
7186
|
};
|
|
7185
7187
|
}
|
|
7186
7188
|
/**
|
|
@@ -7198,7 +7200,7 @@
|
|
|
7198
7200
|
}
|
|
7199
7201
|
if (current.className) {
|
|
7200
7202
|
const classes = current.className.toString().split(/\s+/).slice(0, 2);
|
|
7201
|
-
selector += `.${classes.join(
|
|
7203
|
+
selector += `.${classes.join(".")}`;
|
|
7202
7204
|
}
|
|
7203
7205
|
// Add nth-child if no unique identifier
|
|
7204
7206
|
if (!current.id && !current.className) {
|
|
@@ -7209,26 +7211,38 @@
|
|
|
7209
7211
|
path.unshift(selector);
|
|
7210
7212
|
current = current.parentElement;
|
|
7211
7213
|
}
|
|
7212
|
-
return path.join(
|
|
7214
|
+
return path.join(" > ");
|
|
7213
7215
|
}
|
|
7214
7216
|
/**
|
|
7215
7217
|
* Check if field should be masked
|
|
7216
7218
|
*/
|
|
7217
7219
|
isSensitiveField(element) {
|
|
7218
|
-
const sensitiveTypes = [
|
|
7219
|
-
const sensitiveNames = [
|
|
7220
|
-
|
|
7221
|
-
|
|
7220
|
+
const sensitiveTypes = ["password", "email", "tel", "ssn", "cc"];
|
|
7221
|
+
const sensitiveNames = [
|
|
7222
|
+
"password",
|
|
7223
|
+
"email",
|
|
7224
|
+
"phone",
|
|
7225
|
+
"credit",
|
|
7226
|
+
"card",
|
|
7227
|
+
"ssn",
|
|
7228
|
+
"social",
|
|
7229
|
+
];
|
|
7230
|
+
const type = element.getAttribute("type")?.toLowerCase();
|
|
7231
|
+
const name = element.getAttribute("name")?.toLowerCase();
|
|
7222
7232
|
const className = element.className.toLowerCase();
|
|
7223
|
-
return sensitiveTypes.includes(type ||
|
|
7224
|
-
sensitiveNames.some(term => (name && name.includes(term)) ||
|
|
7225
|
-
className.includes(term));
|
|
7233
|
+
return (sensitiveTypes.includes(type || "") ||
|
|
7234
|
+
sensitiveNames.some((term) => (name && name.includes(term)) || className.includes(term)));
|
|
7226
7235
|
}
|
|
7227
7236
|
/**
|
|
7228
7237
|
* Check if attribute should be masked
|
|
7229
7238
|
*/
|
|
7230
7239
|
isSensitiveAttribute(attrName) {
|
|
7231
|
-
const sensitiveAttrs = [
|
|
7240
|
+
const sensitiveAttrs = [
|
|
7241
|
+
"data-token",
|
|
7242
|
+
"data-key",
|
|
7243
|
+
"data-secret",
|
|
7244
|
+
"authorization",
|
|
7245
|
+
];
|
|
7232
7246
|
return sensitiveAttrs.includes(attrName.toLowerCase());
|
|
7233
7247
|
}
|
|
7234
7248
|
/**
|
|
@@ -7254,7 +7268,7 @@
|
|
|
7254
7268
|
*/
|
|
7255
7269
|
sendBatch() {
|
|
7256
7270
|
if (this.events.length === 0) {
|
|
7257
|
-
console.log(
|
|
7271
|
+
console.log("[Zaplier] No events to send in batch");
|
|
7258
7272
|
return;
|
|
7259
7273
|
}
|
|
7260
7274
|
const batch = [...this.events];
|
|
@@ -7266,44 +7280,35 @@
|
|
|
7266
7280
|
metadata: {
|
|
7267
7281
|
userAgent: navigator.userAgent,
|
|
7268
7282
|
timestamp: Date.now(),
|
|
7269
|
-
compression: this.config.compressionEnabled
|
|
7270
|
-
}
|
|
7283
|
+
compression: this.config.compressionEnabled,
|
|
7284
|
+
},
|
|
7271
7285
|
};
|
|
7272
7286
|
// This will be handled by the anti-adblock manager
|
|
7273
7287
|
this.sendToBackend(payload);
|
|
7274
7288
|
}
|
|
7275
7289
|
/**
|
|
7276
|
-
* Set
|
|
7290
|
+
* Set SDK instance for transport
|
|
7277
7291
|
*/
|
|
7278
|
-
|
|
7279
|
-
this.
|
|
7292
|
+
setSDKInstance(sdk) {
|
|
7293
|
+
this.sdkInstance = sdk;
|
|
7280
7294
|
}
|
|
7281
7295
|
/**
|
|
7282
|
-
* Send
|
|
7296
|
+
* Send replay batch via SDK's transport system
|
|
7283
7297
|
*/
|
|
7284
7298
|
async sendToBackend(payload) {
|
|
7285
7299
|
try {
|
|
7286
|
-
|
|
7287
|
-
|
|
7288
|
-
|
|
7289
|
-
const result = await this.antiAdblockManager.send(payload, '/replays/record');
|
|
7290
|
-
if (result.success) {
|
|
7291
|
-
console.log('[Zaplier] Session replay sent via WebRTC');
|
|
7292
|
-
return; // Success via WebRTC
|
|
7293
|
-
}
|
|
7294
|
-
console.log('[Zaplier] WebRTC failed, falling back to fetch');
|
|
7300
|
+
if (!this.sdkInstance) {
|
|
7301
|
+
console.error("[Zaplier] No SDK instance available for replay transport");
|
|
7302
|
+
return;
|
|
7295
7303
|
}
|
|
7296
|
-
|
|
7297
|
-
const apiEndpoint = window.zaplier_config?.apiEndpoint || 'http://localhost:3001';
|
|
7298
|
-
const token = window.zaplier_config?.token || 'ws_demo_token';
|
|
7299
|
-
const url = `${apiEndpoint}/replays/record?token=${token}`;
|
|
7300
|
-
console.log(`[Zaplier] Sending replay batch to ${url}`);
|
|
7304
|
+
console.log(`[Zaplier] Sending replay batch via SDK transport`);
|
|
7301
7305
|
console.log(`[Zaplier] Payload:`, {
|
|
7302
7306
|
sessionId: payload.sessionId,
|
|
7303
7307
|
eventCount: payload.events.length,
|
|
7304
|
-
hasMetadata: !!payload.metadata
|
|
7308
|
+
hasMetadata: !!payload.metadata,
|
|
7305
7309
|
});
|
|
7306
|
-
|
|
7310
|
+
// Use SDK's sendReplayBatch method
|
|
7311
|
+
const result = await this.sdkInstance.sendReplayBatch({
|
|
7307
7312
|
sessionId: payload.sessionId,
|
|
7308
7313
|
events: payload.events,
|
|
7309
7314
|
metadata: {
|
|
@@ -7311,29 +7316,18 @@
|
|
|
7311
7316
|
duration: Date.now() - (performance.timeOrigin || Date.now()),
|
|
7312
7317
|
funnelSteps: [],
|
|
7313
7318
|
hasConversion: false,
|
|
7314
|
-
...payload.metadata
|
|
7315
|
-
}
|
|
7316
|
-
};
|
|
7317
|
-
// Fallback to standard fetch
|
|
7318
|
-
const response = await fetch(url, {
|
|
7319
|
-
method: 'POST',
|
|
7320
|
-
headers: { 'Content-Type': 'application/json' },
|
|
7321
|
-
body: JSON.stringify(requestBody)
|
|
7319
|
+
...payload.metadata,
|
|
7320
|
+
},
|
|
7322
7321
|
});
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
console.error('[Zaplier] Session replay batch failed:', {
|
|
7326
|
-
status: response.status,
|
|
7327
|
-
statusText: response.statusText,
|
|
7328
|
-
response: responseText
|
|
7329
|
-
});
|
|
7322
|
+
if (result && result.success) {
|
|
7323
|
+
console.log("[Zaplier] Session replay batch sent successfully");
|
|
7330
7324
|
}
|
|
7331
7325
|
else {
|
|
7332
|
-
console.
|
|
7326
|
+
console.error("[Zaplier] Session replay batch failed:", result);
|
|
7333
7327
|
}
|
|
7334
7328
|
}
|
|
7335
7329
|
catch (error) {
|
|
7336
|
-
console.error(
|
|
7330
|
+
console.error("[Zaplier] Session replay error:", error);
|
|
7337
7331
|
}
|
|
7338
7332
|
}
|
|
7339
7333
|
/**
|
|
@@ -7381,7 +7375,7 @@
|
|
|
7381
7375
|
*/
|
|
7382
7376
|
class ZaplierSDK {
|
|
7383
7377
|
constructor(userConfig) {
|
|
7384
|
-
this.version = "3.0
|
|
7378
|
+
this.version = "1.3.0";
|
|
7385
7379
|
this.isInitialized = false;
|
|
7386
7380
|
this.eventQueue = [];
|
|
7387
7381
|
/**
|
|
@@ -7451,19 +7445,58 @@
|
|
|
7451
7445
|
this.sessionId = this.generateSessionId();
|
|
7452
7446
|
}
|
|
7453
7447
|
const sessionId = this.sessionId;
|
|
7448
|
+
// When explicitly enabled, use 100% sample rate
|
|
7454
7449
|
this.replayEngine = new SessionReplayEngine(sessionId, {
|
|
7455
|
-
sampleRate:
|
|
7450
|
+
sampleRate: 1.0, // Force 100% when explicitly enabled
|
|
7456
7451
|
maskSensitiveFields: this.config.replayMaskInputs,
|
|
7457
7452
|
compressionEnabled: true,
|
|
7458
7453
|
});
|
|
7459
7454
|
// Connect to anti-adblock manager
|
|
7460
7455
|
if (this.antiAdblockManager) {
|
|
7461
|
-
this.replayEngine.
|
|
7456
|
+
this.replayEngine.setSDKInstance(this);
|
|
7457
|
+
}
|
|
7458
|
+
const started = this.replayEngine.start();
|
|
7459
|
+
if (this.config.debug) {
|
|
7460
|
+
console.log("[Zaplier] Replay enabled", {
|
|
7461
|
+
started,
|
|
7462
|
+
isRecording: this.replayEngine.isRecording(),
|
|
7463
|
+
});
|
|
7462
7464
|
}
|
|
7463
|
-
this.replayEngine.start();
|
|
7464
7465
|
}
|
|
7465
|
-
if (this.
|
|
7466
|
-
|
|
7466
|
+
else if (this.replayEngine) {
|
|
7467
|
+
// If engine already exists but isn't recording, recreate it with 100% sample rate
|
|
7468
|
+
if (!this.replayEngine.isRecording()) {
|
|
7469
|
+
// Stop and recreate with 100% sample rate
|
|
7470
|
+
this.replayEngine.stop();
|
|
7471
|
+
this.replayEngine = undefined;
|
|
7472
|
+
// Recreate with 100% sample rate
|
|
7473
|
+
if (!this.sessionId) {
|
|
7474
|
+
this.sessionId = this.generateSessionId();
|
|
7475
|
+
}
|
|
7476
|
+
const sessionId = this.sessionId;
|
|
7477
|
+
this.replayEngine = new SessionReplayEngine(sessionId, {
|
|
7478
|
+
sampleRate: 1.0, // Force 100% when explicitly enabled
|
|
7479
|
+
maskSensitiveFields: this.config.replayMaskInputs,
|
|
7480
|
+
compressionEnabled: true,
|
|
7481
|
+
});
|
|
7482
|
+
// Connect to anti-adblock manager
|
|
7483
|
+
if (this.antiAdblockManager) {
|
|
7484
|
+
this.replayEngine.setSDKInstance(this);
|
|
7485
|
+
}
|
|
7486
|
+
const started = this.replayEngine.start();
|
|
7487
|
+
if (this.config.debug) {
|
|
7488
|
+
console.log("[Zaplier] Replay engine recreated with 100% sample rate", { started, isRecording: this.replayEngine.isRecording() });
|
|
7489
|
+
}
|
|
7490
|
+
}
|
|
7491
|
+
else {
|
|
7492
|
+
// Already recording, just log
|
|
7493
|
+
if (this.config.debug) {
|
|
7494
|
+
console.log("[Zaplier] Replay already recording");
|
|
7495
|
+
}
|
|
7496
|
+
}
|
|
7497
|
+
}
|
|
7498
|
+
if (this.config.debug && !this.replayEngine) {
|
|
7499
|
+
console.log("[Zaplier] Replay enabled (will start when SDK initializes)");
|
|
7467
7500
|
}
|
|
7468
7501
|
},
|
|
7469
7502
|
disable: () => {
|
|
@@ -7490,7 +7523,7 @@
|
|
|
7490
7523
|
});
|
|
7491
7524
|
// Connect to anti-adblock manager
|
|
7492
7525
|
if (this.antiAdblockManager) {
|
|
7493
|
-
this.replayEngine.
|
|
7526
|
+
this.replayEngine.setSDKInstance(this);
|
|
7494
7527
|
}
|
|
7495
7528
|
return this.replayEngine.start();
|
|
7496
7529
|
}
|
|
@@ -7586,18 +7619,23 @@
|
|
|
7586
7619
|
}
|
|
7587
7620
|
// Initialize Session Replay Engine
|
|
7588
7621
|
if (this.config.replay) {
|
|
7622
|
+
// When replay is explicitly enabled, use 100% sample rate to ensure recording
|
|
7623
|
+
// The default replaySampling (0.1) is only for automatic/production sampling
|
|
7624
|
+
const sampleRate = this.config.replay === true ? 1.0 : this.config.replaySampling;
|
|
7589
7625
|
this.replayEngine = new SessionReplayEngine(this.sessionId, {
|
|
7590
|
-
sampleRate:
|
|
7626
|
+
sampleRate: sampleRate,
|
|
7591
7627
|
maskSensitiveFields: this.config.replayMaskInputs,
|
|
7592
7628
|
compressionEnabled: true,
|
|
7593
7629
|
});
|
|
7594
|
-
// Connect
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
}
|
|
7598
|
-
this.replayEngine.start();
|
|
7630
|
+
// Connect SDK instance for transport
|
|
7631
|
+
this.replayEngine.setSDKInstance(this);
|
|
7632
|
+
const started = this.replayEngine.start();
|
|
7599
7633
|
if (this.config.debug) {
|
|
7600
|
-
console.log("[Zaplier] Session Replay started"
|
|
7634
|
+
console.log("[Zaplier] Session Replay started", {
|
|
7635
|
+
started,
|
|
7636
|
+
sampleRate,
|
|
7637
|
+
isRecording: this.replayEngine.isRecording(),
|
|
7638
|
+
});
|
|
7601
7639
|
}
|
|
7602
7640
|
}
|
|
7603
7641
|
// Initialize Heatmap Engine
|
|
@@ -7876,6 +7914,46 @@
|
|
|
7876
7914
|
}
|
|
7877
7915
|
}
|
|
7878
7916
|
}
|
|
7917
|
+
/**
|
|
7918
|
+
* Send session replay batch to backend
|
|
7919
|
+
*/
|
|
7920
|
+
async sendReplayBatch(replayData) {
|
|
7921
|
+
if (!this.isInitialized) {
|
|
7922
|
+
console.error("[Zaplier] SDK not initialized for replay batch sending");
|
|
7923
|
+
return { success: false, error: "SDK not initialized" };
|
|
7924
|
+
}
|
|
7925
|
+
try {
|
|
7926
|
+
const payload = {
|
|
7927
|
+
sessionId: replayData.sessionId,
|
|
7928
|
+
userId: this.backendVisitorId,
|
|
7929
|
+
events: replayData.events,
|
|
7930
|
+
metadata: {
|
|
7931
|
+
...replayData.metadata,
|
|
7932
|
+
visitorId: this.backendVisitorId,
|
|
7933
|
+
fingerprintHash: this.fingerprint?.hash,
|
|
7934
|
+
},
|
|
7935
|
+
};
|
|
7936
|
+
if (this.config.debug) {
|
|
7937
|
+
console.log("[Zaplier] Sending replay batch:", {
|
|
7938
|
+
sessionId: payload.sessionId,
|
|
7939
|
+
eventCount: payload.events.length,
|
|
7940
|
+
hasMetadata: !!payload.metadata,
|
|
7941
|
+
});
|
|
7942
|
+
}
|
|
7943
|
+
// Use anti-adblock transport or standard HTTP
|
|
7944
|
+
const result = await this.makeRequest(`/replays/record?token=${encodeURIComponent(this.config.token)}`, payload, "POST");
|
|
7945
|
+
if (this.config.debug) {
|
|
7946
|
+
console.log("[Zaplier] Replay batch result:", result);
|
|
7947
|
+
}
|
|
7948
|
+
return result;
|
|
7949
|
+
}
|
|
7950
|
+
catch (error) {
|
|
7951
|
+
if (this.config.debug) {
|
|
7952
|
+
console.error("[Zaplier] Replay batch sending failed:", error);
|
|
7953
|
+
}
|
|
7954
|
+
return { success: false, error: error instanceof Error ? error.message : "Unknown error" };
|
|
7955
|
+
}
|
|
7956
|
+
}
|
|
7879
7957
|
/**
|
|
7880
7958
|
* Make HTTP request to backend using anti-adblock system
|
|
7881
7959
|
*/
|