@zaplier/sdk 1.3.6 → 1.4.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 +23 -187
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +23 -187
- package/dist/index.esm.js.map +1 -1
- package/dist/sdk.js +23 -187
- package/dist/sdk.js.map +1 -1
- package/dist/sdk.min.js +1 -1
- package/dist/src/modules/session-replay.d.ts +4 -22
- 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
|
@@ -19010,35 +19010,25 @@ var n;
|
|
|
19010
19010
|
!function(t2) {
|
|
19011
19011
|
t2[t2.NotStarted = 0] = "NotStarted", t2[t2.Running = 1] = "Running", t2[t2.Stopped = 2] = "Stopped";
|
|
19012
19012
|
}(n || (n = {}));
|
|
19013
|
-
const { takeFullSnapshot } = record;
|
|
19014
19013
|
|
|
19015
19014
|
/**
|
|
19016
|
-
* Session Replay Engine
|
|
19017
|
-
*
|
|
19015
|
+
* Session Replay Engine - Simplified Implementation
|
|
19016
|
+
* Based on official rrweb example for maximum compatibility
|
|
19018
19017
|
*/
|
|
19019
19018
|
class SessionReplayEngine {
|
|
19020
19019
|
constructor(sessionId, config = {}) {
|
|
19021
19020
|
this.events = [];
|
|
19022
19021
|
this.isActive = false;
|
|
19023
|
-
this.hasFullSnapshot = false;
|
|
19024
|
-
this.startTime = 0;
|
|
19025
19022
|
this.sessionId = sessionId;
|
|
19026
19023
|
this.config = {
|
|
19027
19024
|
enabled: true,
|
|
19028
|
-
sampleRate: 1.0,
|
|
19029
|
-
|
|
19030
|
-
maxEventBuffer: 1000,
|
|
19031
|
-
batchInterval: 2000, // Send every 2 seconds for faster testing
|
|
19032
|
-
captureClicks: true,
|
|
19033
|
-
captureScrolls: true,
|
|
19034
|
-
captureInputs: true,
|
|
19035
|
-
captureMouseMoves: false, // Disabled by default for performance
|
|
19036
|
-
compressionEnabled: true,
|
|
19025
|
+
sampleRate: 1.0,
|
|
19026
|
+
batchInterval: 10000, // 10 seconds like official example
|
|
19037
19027
|
...config,
|
|
19038
19028
|
};
|
|
19039
19029
|
}
|
|
19040
19030
|
/**
|
|
19041
|
-
* Start session replay recording
|
|
19031
|
+
* Start session replay recording - Simplified like official example
|
|
19042
19032
|
*/
|
|
19043
19033
|
start() {
|
|
19044
19034
|
if (!this.config.enabled || this.isActive) {
|
|
@@ -19049,58 +19039,16 @@ class SessionReplayEngine {
|
|
|
19049
19039
|
return false;
|
|
19050
19040
|
}
|
|
19051
19041
|
try {
|
|
19052
|
-
//
|
|
19053
|
-
// Using minimal configuration to avoid known bugs in alpha versions
|
|
19054
|
-
// blockSelector and maskTextSelector removed due to node.matches error
|
|
19042
|
+
// Simple rrweb recording configuration like official example
|
|
19055
19043
|
this.rrwebStopRecord = record({
|
|
19056
19044
|
emit: (event) => {
|
|
19057
|
-
|
|
19045
|
+
// Simple event capture - no processing
|
|
19046
|
+
this.events.push(event);
|
|
19058
19047
|
},
|
|
19059
|
-
maskAllInputs: this.config.maskSensitiveFields,
|
|
19060
|
-
// maskTextSelector removed - causes node.matches error in some cases
|
|
19061
|
-
// blockSelector removed - causes node.matches error
|
|
19062
|
-
recordCanvas: false, // Disable canvas recording for performance
|
|
19063
|
-
recordCrossOriginIframes: false,
|
|
19064
|
-
inlineStylesheet: true,
|
|
19065
|
-
collectFonts: false, // Disable font collection for smaller payloads
|
|
19066
19048
|
});
|
|
19067
19049
|
this.isActive = true;
|
|
19068
|
-
this.hasFullSnapshot = false;
|
|
19069
|
-
this.startTime = Date.now();
|
|
19070
19050
|
this.startBatchTimer();
|
|
19071
|
-
|
|
19072
|
-
// where FullSnapshot is sometimes not created as the first event
|
|
19073
|
-
setTimeout(() => {
|
|
19074
|
-
console.log("[Zaplier] Forcing immediate FullSnapshot to ensure correct event order...");
|
|
19075
|
-
try {
|
|
19076
|
-
takeFullSnapshot(true); // Force a new FullSnapshot immediately
|
|
19077
|
-
console.log("[Zaplier] FullSnapshot manually triggered");
|
|
19078
|
-
}
|
|
19079
|
-
catch (error) {
|
|
19080
|
-
console.error("[Zaplier] Failed to force FullSnapshot:", error);
|
|
19081
|
-
}
|
|
19082
|
-
}, 100); // Very short delay to ensure it comes first
|
|
19083
|
-
// Set timeout to check if FullSnapshot was captured
|
|
19084
|
-
this.snapshotTimeout = window.setTimeout(() => {
|
|
19085
|
-
if (!this.hasFullSnapshot) {
|
|
19086
|
-
console.error("[Zaplier] CRITICAL: FullSnapshot not captured after 5 seconds!", {
|
|
19087
|
-
eventsReceived: this.events.length,
|
|
19088
|
-
eventTypes: this.events.map((e) => e.type).slice(0, 10),
|
|
19089
|
-
});
|
|
19090
|
-
// Try one more forced snapshot as last resort
|
|
19091
|
-
try {
|
|
19092
|
-
console.warn("[Zaplier] Last resort: forcing FullSnapshot...");
|
|
19093
|
-
takeFullSnapshot(true);
|
|
19094
|
-
}
|
|
19095
|
-
catch (error) {
|
|
19096
|
-
console.error("[Zaplier] Failed to create emergency FullSnapshot:", error);
|
|
19097
|
-
}
|
|
19098
|
-
}
|
|
19099
|
-
else {
|
|
19100
|
-
console.log("[Zaplier] ✅ FullSnapshot confirmed captured");
|
|
19101
|
-
}
|
|
19102
|
-
}, 5000);
|
|
19103
|
-
console.log("[Zaplier] Session replay started with rrweb");
|
|
19051
|
+
console.log("[Zaplier] Session replay started - simple mode");
|
|
19104
19052
|
return true;
|
|
19105
19053
|
}
|
|
19106
19054
|
catch (error) {
|
|
@@ -19124,87 +19072,9 @@ class SessionReplayEngine {
|
|
|
19124
19072
|
clearInterval(this.batchTimer);
|
|
19125
19073
|
this.batchTimer = undefined;
|
|
19126
19074
|
}
|
|
19127
|
-
if (this.snapshotTimeout) {
|
|
19128
|
-
clearTimeout(this.snapshotTimeout);
|
|
19129
|
-
this.snapshotTimeout = undefined;
|
|
19130
|
-
}
|
|
19131
19075
|
// Send final batch
|
|
19132
19076
|
this.sendBatch();
|
|
19133
19077
|
}
|
|
19134
|
-
/**
|
|
19135
|
-
* Handle events from rrweb
|
|
19136
|
-
*/
|
|
19137
|
-
handleRRWebEvent(event) {
|
|
19138
|
-
try {
|
|
19139
|
-
// Log ALL events until we get FullSnapshot, then log first 5
|
|
19140
|
-
const shouldLog = !this.hasFullSnapshot || this.events.length < 5;
|
|
19141
|
-
if (shouldLog) {
|
|
19142
|
-
const eventTypeNames = {
|
|
19143
|
-
[EventType.DomContentLoaded]: "DomContentLoaded",
|
|
19144
|
-
[EventType.Load]: "Load",
|
|
19145
|
-
[EventType.FullSnapshot]: "FullSnapshot",
|
|
19146
|
-
[EventType.IncrementalSnapshot]: "IncrementalSnapshot",
|
|
19147
|
-
[EventType.Meta]: "Meta",
|
|
19148
|
-
[EventType.Custom]: "Custom",
|
|
19149
|
-
[EventType.Plugin]: "Plugin",
|
|
19150
|
-
};
|
|
19151
|
-
console.log(`[Zaplier] Received event type ${event.type} (${eventTypeNames[event.type] || "Unknown"})`, {
|
|
19152
|
-
timestamp: new Date(event.timestamp).toISOString(),
|
|
19153
|
-
isFirst: this.events.length === 0,
|
|
19154
|
-
totalEvents: this.events.length + 1,
|
|
19155
|
-
});
|
|
19156
|
-
}
|
|
19157
|
-
// Check if this is a FullSnapshot
|
|
19158
|
-
if (event.type === EventType.FullSnapshot) {
|
|
19159
|
-
this.hasFullSnapshot = true;
|
|
19160
|
-
console.log("[Zaplier] ✅ FullSnapshot captured! Replay will work correctly.");
|
|
19161
|
-
// Clear timeout since we got the snapshot
|
|
19162
|
-
if (this.snapshotTimeout) {
|
|
19163
|
-
clearTimeout(this.snapshotTimeout);
|
|
19164
|
-
this.snapshotTimeout = undefined;
|
|
19165
|
-
}
|
|
19166
|
-
}
|
|
19167
|
-
else if (this.events.length === 0) {
|
|
19168
|
-
// First event is NOT a FullSnapshot - this is a problem!
|
|
19169
|
-
console.error(`[Zaplier] ⚠️ WARNING: First event is type ${event.type}, not FullSnapshot! Replay may not work.`);
|
|
19170
|
-
}
|
|
19171
|
-
// Add event to buffer
|
|
19172
|
-
this.addEvent(event);
|
|
19173
|
-
// If we just got the FullSnapshot and have events, try sending immediately
|
|
19174
|
-
if (event.type === EventType.FullSnapshot && this.events.length > 0) {
|
|
19175
|
-
// Small delay to ensure all initial events are captured
|
|
19176
|
-
setTimeout(() => {
|
|
19177
|
-
this.sendBatch();
|
|
19178
|
-
}, 100);
|
|
19179
|
-
}
|
|
19180
|
-
}
|
|
19181
|
-
catch (error) {
|
|
19182
|
-
// Silently ignore errors from rrweb to prevent breaking the app
|
|
19183
|
-
// The error is likely from rrweb's internal processing
|
|
19184
|
-
console.warn("[Zaplier] Error handling rrweb event:", error);
|
|
19185
|
-
}
|
|
19186
|
-
}
|
|
19187
|
-
/**
|
|
19188
|
-
* Add event to buffer
|
|
19189
|
-
*/
|
|
19190
|
-
addEvent(event) {
|
|
19191
|
-
this.events.push(event);
|
|
19192
|
-
// Prevent memory overflow
|
|
19193
|
-
if (this.events.length > this.config.maxEventBuffer) {
|
|
19194
|
-
// Keep FullSnapshot if present
|
|
19195
|
-
const fullSnapshotIndex = this.events.findIndex((e) => e.type === EventType.FullSnapshot);
|
|
19196
|
-
if (fullSnapshotIndex >= 0 &&
|
|
19197
|
-
fullSnapshotIndex < this.events.length - this.config.maxEventBuffer) {
|
|
19198
|
-
// Keep snapshot and recent events
|
|
19199
|
-
const snapshot = this.events[fullSnapshotIndex];
|
|
19200
|
-
const recentEvents = this.events.slice(-this.config.maxEventBuffer + 1);
|
|
19201
|
-
this.events = [snapshot, ...recentEvents];
|
|
19202
|
-
}
|
|
19203
|
-
else {
|
|
19204
|
-
this.events = this.events.slice(-this.config.maxEventBuffer);
|
|
19205
|
-
}
|
|
19206
|
-
}
|
|
19207
|
-
}
|
|
19208
19078
|
/**
|
|
19209
19079
|
* Start batch timer
|
|
19210
19080
|
*/
|
|
@@ -19214,39 +19084,29 @@ class SessionReplayEngine {
|
|
|
19214
19084
|
}, this.config.batchInterval);
|
|
19215
19085
|
}
|
|
19216
19086
|
/**
|
|
19217
|
-
* Send batch of events
|
|
19087
|
+
* Send batch of events - Simplified like official example
|
|
19218
19088
|
*/
|
|
19219
19089
|
sendBatch() {
|
|
19220
19090
|
if (this.events.length === 0) {
|
|
19221
19091
|
return;
|
|
19222
19092
|
}
|
|
19223
|
-
//
|
|
19224
|
-
if (!this.hasFullSnapshot) {
|
|
19225
|
-
const waitTime = Date.now() - this.startTime;
|
|
19226
|
-
// Only log every 2 seconds to avoid spam
|
|
19227
|
-
if (waitTime % 2000 < 100) {
|
|
19228
|
-
console.warn(`[Zaplier] Waiting for FullSnapshot before sending batch... (${Math.floor(waitTime / 1000)}s). Events so far: ${this.events.length}, types:`, this.events.map((e) => e.type).slice(0, 5));
|
|
19229
|
-
}
|
|
19230
|
-
return; // Don't send without FullSnapshot
|
|
19231
|
-
}
|
|
19232
|
-
const batch = [...this.events];
|
|
19233
|
-
this.events = [];
|
|
19234
|
-
// Verify batch has FullSnapshot
|
|
19235
|
-
const hasSnapshot = batch.some((e) => e.type === EventType.FullSnapshot);
|
|
19236
|
-
if (!hasSnapshot && this.hasFullSnapshot) {
|
|
19237
|
-
console.warn("[Zaplier] Batch missing FullSnapshot, but one was captured earlier");
|
|
19238
|
-
}
|
|
19239
|
-
console.log(`[Zaplier] Sending batch with ${batch.length} events for session ${this.sessionId}`, { hasSnapshot, firstEventType: batch[0]?.type });
|
|
19093
|
+
// Simple payload structure like official example
|
|
19240
19094
|
const payload = {
|
|
19241
19095
|
sessionId: this.sessionId,
|
|
19242
|
-
events:
|
|
19096
|
+
events: [...this.events], // Copy events array
|
|
19243
19097
|
metadata: {
|
|
19244
19098
|
userAgent: navigator.userAgent,
|
|
19245
19099
|
timestamp: Date.now(),
|
|
19246
|
-
|
|
19100
|
+
startUrl: window.location.href,
|
|
19101
|
+
duration: Date.now() - (performance.timeOrigin || Date.now()),
|
|
19102
|
+
funnelSteps: [],
|
|
19103
|
+
hasConversion: false,
|
|
19247
19104
|
},
|
|
19248
19105
|
};
|
|
19249
|
-
//
|
|
19106
|
+
// Reset events array like official example
|
|
19107
|
+
this.events = [];
|
|
19108
|
+
console.log(`[Zaplier] Sending batch with ${payload.events.length} events`);
|
|
19109
|
+
// Send to backend
|
|
19250
19110
|
this.sendToBackend(payload);
|
|
19251
19111
|
}
|
|
19252
19112
|
/**
|
|
@@ -19264,24 +19124,8 @@ class SessionReplayEngine {
|
|
|
19264
19124
|
console.error("[Zaplier] No SDK instance available for replay transport");
|
|
19265
19125
|
return;
|
|
19266
19126
|
}
|
|
19267
|
-
|
|
19268
|
-
|
|
19269
|
-
sessionId: payload.sessionId,
|
|
19270
|
-
eventCount: payload.events.length,
|
|
19271
|
-
hasMetadata: !!payload.metadata,
|
|
19272
|
-
});
|
|
19273
|
-
// Use SDK's sendReplayBatch method
|
|
19274
|
-
const result = await this.sdkInstance.sendReplayBatch({
|
|
19275
|
-
sessionId: payload.sessionId,
|
|
19276
|
-
events: payload.events,
|
|
19277
|
-
metadata: {
|
|
19278
|
-
startUrl: window.location.href,
|
|
19279
|
-
duration: Date.now() - (performance.timeOrigin || Date.now()),
|
|
19280
|
-
funnelSteps: [],
|
|
19281
|
-
hasConversion: false,
|
|
19282
|
-
...payload.metadata,
|
|
19283
|
-
},
|
|
19284
|
-
});
|
|
19127
|
+
// Use SDK's sendReplayBatch method with simplified payload
|
|
19128
|
+
const result = await this.sdkInstance.sendReplayBatch(payload);
|
|
19285
19129
|
if (result && result.success) {
|
|
19286
19130
|
console.log("[Zaplier] Session replay batch sent successfully");
|
|
19287
19131
|
}
|
|
@@ -19338,7 +19182,7 @@ const DEFAULT_CONFIG = {
|
|
|
19338
19182
|
*/
|
|
19339
19183
|
class ZaplierSDK {
|
|
19340
19184
|
constructor(userConfig) {
|
|
19341
|
-
this.version = "1.3.
|
|
19185
|
+
this.version = "1.3.7";
|
|
19342
19186
|
this.isInitialized = false;
|
|
19343
19187
|
this.eventQueue = [];
|
|
19344
19188
|
/**
|
|
@@ -19411,8 +19255,6 @@ class ZaplierSDK {
|
|
|
19411
19255
|
// When explicitly enabled, use 100% sample rate
|
|
19412
19256
|
this.replayEngine = new SessionReplayEngine(sessionId, {
|
|
19413
19257
|
sampleRate: 1.0, // Force 100% when explicitly enabled
|
|
19414
|
-
maskSensitiveFields: this.config.replayMaskInputs,
|
|
19415
|
-
compressionEnabled: true,
|
|
19416
19258
|
});
|
|
19417
19259
|
// Connect to anti-adblock manager
|
|
19418
19260
|
if (this.antiAdblockManager) {
|
|
@@ -19439,8 +19281,6 @@ class ZaplierSDK {
|
|
|
19439
19281
|
const sessionId = this.sessionId;
|
|
19440
19282
|
this.replayEngine = new SessionReplayEngine(sessionId, {
|
|
19441
19283
|
sampleRate: 1.0, // Force 100% when explicitly enabled
|
|
19442
|
-
maskSensitiveFields: this.config.replayMaskInputs,
|
|
19443
|
-
compressionEnabled: true,
|
|
19444
19284
|
});
|
|
19445
19285
|
// Connect to anti-adblock manager
|
|
19446
19286
|
if (this.antiAdblockManager) {
|
|
@@ -19481,8 +19321,6 @@ class ZaplierSDK {
|
|
|
19481
19321
|
const sessionId = this.sessionId;
|
|
19482
19322
|
this.replayEngine = new SessionReplayEngine(sessionId, {
|
|
19483
19323
|
sampleRate: 1.0, // Force recording when manually started
|
|
19484
|
-
maskSensitiveFields: this.config.replayMaskInputs,
|
|
19485
|
-
compressionEnabled: true,
|
|
19486
19324
|
});
|
|
19487
19325
|
// Connect to anti-adblock manager
|
|
19488
19326
|
if (this.antiAdblockManager) {
|
|
@@ -19587,8 +19425,6 @@ class ZaplierSDK {
|
|
|
19587
19425
|
const sampleRate = this.config.replay === true ? 1.0 : this.config.replaySampling;
|
|
19588
19426
|
this.replayEngine = new SessionReplayEngine(this.sessionId, {
|
|
19589
19427
|
sampleRate: sampleRate,
|
|
19590
|
-
maskSensitiveFields: this.config.replayMaskInputs,
|
|
19591
|
-
compressionEnabled: true,
|
|
19592
19428
|
});
|
|
19593
19429
|
// Connect SDK instance for transport
|
|
19594
19430
|
this.replayEngine.setSDKInstance(this);
|