@sprig-technologies/sprig-browser 2.33.2 → 2.34.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/{core-C0XvmpIu.js → core-DE6rbUl1.js} +420 -408
- package/dist/core-i4jnjCfb.cjs +12 -0
- package/dist/core.cjs +1 -1
- package/dist/core.d.ts +20 -0
- package/dist/core.js +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +20 -0
- package/dist/index.js +2 -2
- package/dist/{metricsReporter-uTmb1eaJ.js → metricsReporter-CEzz54S2.js} +2 -2
- package/dist/{metricsReporter-BLXrIaei.cjs → metricsReporter-Cc-ZSIZD.cjs} +1 -1
- package/dist/replay.cjs +1 -1
- package/dist/replay.js +346 -339
- package/dist/{view-yOVTCqu5.cjs → view-Bze4Vd-1.cjs} +3 -3
- package/dist/{view-DuNLA499.js → view-C3KUMRoa.js} +228 -226
- package/package.json +1 -1
- package/dist/core-B164snRL.cjs +0 -12
package/dist/replay.js
CHANGED
|
@@ -1,98 +1,98 @@
|
|
|
1
1
|
var st = Object.defineProperty;
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { b as d, s as
|
|
5
|
-
var B = ((e) => (e[e.DomContentLoaded = 0] = "DomContentLoaded", e[e.Load = 1] = "Load", e[e.FullSnapshot = 2] = "FullSnapshot", e[e.IncrementalSnapshot = 3] = "IncrementalSnapshot", e[e.Meta = 4] = "Meta", e[e.Custom = 5] = "Custom", e[e.Plugin = 6] = "Plugin", e))(B || {}),
|
|
6
|
-
const
|
|
7
|
-
let
|
|
8
|
-
const
|
|
9
|
-
let
|
|
2
|
+
var it = (e, t, n) => t in e ? st(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
|
|
3
|
+
var X = (e, t, n) => it(e, typeof t != "symbol" ? t + "" : t, n);
|
|
4
|
+
import { b as d, s as z, a as m, v as q, c as dt, g as lt, P as ke, r as Ue, d as ut, e as H, S as Z, f as ct } from "./metricsReporter-CEzz54S2.js";
|
|
5
|
+
var B = ((e) => (e[e.DomContentLoaded = 0] = "DomContentLoaded", e[e.Load = 1] = "Load", e[e.FullSnapshot = 2] = "FullSnapshot", e[e.IncrementalSnapshot = 3] = "IncrementalSnapshot", e[e.Meta = 4] = "Meta", e[e.Custom = 5] = "Custom", e[e.Plugin = 6] = "Plugin", e))(B || {}), U = ((e) => (e[e.Mutation = 0] = "Mutation", e[e.MouseMove = 1] = "MouseMove", e[e.MouseInteraction = 2] = "MouseInteraction", e[e.Scroll = 3] = "Scroll", e[e.ViewportResize = 4] = "ViewportResize", e[e.Input = 5] = "Input", e[e.TouchMove = 6] = "TouchMove", e[e.MediaInteraction = 7] = "MediaInteraction", e[e.StyleSheetRule = 8] = "StyleSheetRule", e[e.CanvasMutation = 9] = "CanvasMutation", e[e.Font = 10] = "Font", e[e.Log = 11] = "Log", e[e.Drag = 12] = "Drag", e[e.StyleDeclaration = 13] = "StyleDeclaration", e[e.Selection = 14] = "Selection", e[e.AdoptedStyleSheet = 15] = "AdoptedStyleSheet", e[e.CustomElement = 16] = "CustomElement", e))(U || {});
|
|
6
|
+
const ae = (e, t) => t.some((n) => e instanceof n);
|
|
7
|
+
let ve, Se;
|
|
8
|
+
const re = /* @__PURE__ */ new WeakMap(), Y = /* @__PURE__ */ new WeakMap(), $ = /* @__PURE__ */ new WeakMap();
|
|
9
|
+
let oe = { get(e, t, n) {
|
|
10
10
|
if (e instanceof IDBTransaction) {
|
|
11
|
-
if (t === "done") return
|
|
11
|
+
if (t === "done") return re.get(e);
|
|
12
12
|
if (t === "store") return n.objectStoreNames[1] ? void 0 : n.objectStore(n.objectStoreNames[0]);
|
|
13
13
|
}
|
|
14
|
-
return
|
|
14
|
+
return M(e[t]);
|
|
15
15
|
}, set: (e, t, n) => (e[t] = n, !0), has: (e, t) => e instanceof IDBTransaction && (t === "done" || t === "store") || t in e };
|
|
16
|
-
function
|
|
17
|
-
|
|
16
|
+
function xe(e) {
|
|
17
|
+
oe = e(oe);
|
|
18
18
|
}
|
|
19
|
-
function
|
|
20
|
-
return (
|
|
21
|
-
return e.apply(se(this), t),
|
|
19
|
+
function pt(e) {
|
|
20
|
+
return (Se || (Se = [IDBCursor.prototype.advance, IDBCursor.prototype.continue, IDBCursor.prototype.continuePrimaryKey])).includes(e) ? function(...t) {
|
|
21
|
+
return e.apply(se(this), t), M(this.request);
|
|
22
22
|
} : function(...t) {
|
|
23
|
-
return
|
|
23
|
+
return M(e.apply(se(this), t));
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
|
-
function
|
|
27
|
-
return typeof e == "function" ?
|
|
28
|
-
if (
|
|
26
|
+
function gt(e) {
|
|
27
|
+
return typeof e == "function" ? pt(e) : (e instanceof IDBTransaction && function(t) {
|
|
28
|
+
if (re.has(t)) return;
|
|
29
29
|
const n = new Promise((a, r) => {
|
|
30
|
-
const
|
|
30
|
+
const o = () => {
|
|
31
31
|
r(t.error || new DOMException("AbortError", "AbortError"));
|
|
32
32
|
};
|
|
33
33
|
t.oncomplete = () => {
|
|
34
34
|
a();
|
|
35
|
-
}, t.onerror =
|
|
35
|
+
}, t.onerror = o, t.onabort = o;
|
|
36
36
|
});
|
|
37
|
-
|
|
38
|
-
}(e),
|
|
37
|
+
re.set(t, n);
|
|
38
|
+
}(e), ae(e, ve || (ve = [IDBDatabase, IDBObjectStore, IDBIndex, IDBCursor, IDBTransaction])) ? new Proxy(e, oe) : e);
|
|
39
39
|
}
|
|
40
|
-
function
|
|
40
|
+
function M(e) {
|
|
41
41
|
if (e instanceof IDBRequest) return function(n) {
|
|
42
|
-
const a = new Promise((r,
|
|
42
|
+
const a = new Promise((r, o) => {
|
|
43
43
|
n.onsuccess = () => {
|
|
44
|
-
r(
|
|
44
|
+
r(M(n.result));
|
|
45
45
|
}, n.onerror = () => {
|
|
46
|
-
|
|
46
|
+
o(n.error);
|
|
47
47
|
};
|
|
48
48
|
});
|
|
49
49
|
return $.set(a, n), a;
|
|
50
50
|
}(e);
|
|
51
|
-
if (
|
|
52
|
-
const t =
|
|
53
|
-
return t !== e && (
|
|
51
|
+
if (Y.has(e)) return Y.get(e);
|
|
52
|
+
const t = gt(e);
|
|
53
|
+
return t !== e && (Y.set(e, t), $.set(t, e)), t;
|
|
54
54
|
}
|
|
55
55
|
const se = (e) => $.get(e);
|
|
56
|
-
function
|
|
56
|
+
function ie(e, { blocked: t } = {}) {
|
|
57
57
|
const n = indexedDB.deleteDatabase(e);
|
|
58
|
-
return t && (n.onblocked = (a) => t(a.oldVersion, a)),
|
|
58
|
+
return t && (n.onblocked = (a) => t(a.oldVersion, a)), M(n).then(() => {
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
|
-
const
|
|
62
|
-
function
|
|
61
|
+
const mt = ["get", "getKey", "getAll", "getAllKeys", "count"], wt = ["put", "add", "delete", "clear"], ee = /* @__PURE__ */ new Map();
|
|
62
|
+
function De(e, t) {
|
|
63
63
|
if (!(e instanceof IDBDatabase) || t in e || typeof t != "string") return;
|
|
64
|
-
if (
|
|
65
|
-
const n = t.replace(/FromIndex$/, ""), a = t !== n, r =
|
|
66
|
-
if (!(n in (a ? IDBIndex : IDBObjectStore).prototype) || !r && !
|
|
67
|
-
const
|
|
68
|
-
const i = this.transaction(
|
|
69
|
-
let
|
|
70
|
-
return a && (
|
|
64
|
+
if (ee.get(t)) return ee.get(t);
|
|
65
|
+
const n = t.replace(/FromIndex$/, ""), a = t !== n, r = wt.includes(n);
|
|
66
|
+
if (!(n in (a ? IDBIndex : IDBObjectStore).prototype) || !r && !mt.includes(n)) return;
|
|
67
|
+
const o = async function(s, ...l) {
|
|
68
|
+
const i = this.transaction(s, r ? "readwrite" : "readonly");
|
|
69
|
+
let u = i.store;
|
|
70
|
+
return a && (u = u.index(l.shift())), (await Promise.all([u[n](...l), r && i.done]))[0];
|
|
71
71
|
};
|
|
72
|
-
return
|
|
72
|
+
return ee.set(t, o), o;
|
|
73
73
|
}
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
if (!
|
|
77
|
-
let n =
|
|
78
|
-
return n || (n =
|
|
79
|
-
|
|
74
|
+
xe((e) => ({ ...e, get: (t, n, a) => De(t, n) || e.get(t, n, a), has: (t, n) => !!De(t, n) || e.has(t, n) }));
|
|
75
|
+
const yt = ["continue", "continuePrimaryKey", "advance"], be = {}, de = /* @__PURE__ */ new WeakMap(), Te = /* @__PURE__ */ new WeakMap(), ft = { get(e, t) {
|
|
76
|
+
if (!yt.includes(t)) return e[t];
|
|
77
|
+
let n = be[t];
|
|
78
|
+
return n || (n = be[t] = function(...a) {
|
|
79
|
+
de.set(this, Te.get(this)[t](...a));
|
|
80
80
|
}), n;
|
|
81
81
|
} };
|
|
82
|
-
async function*
|
|
82
|
+
async function* ht(...e) {
|
|
83
83
|
let t = this;
|
|
84
84
|
if (t instanceof IDBCursor || (t = await t.openCursor(...e)), !t) return;
|
|
85
|
-
const n = new Proxy(t,
|
|
86
|
-
for (
|
|
85
|
+
const n = new Proxy(t, ft);
|
|
86
|
+
for (Te.set(n, t), $.set(n, se(t)); t; ) yield n, t = await (de.get(n) || t.continue()), de.delete(n);
|
|
87
87
|
}
|
|
88
|
-
function
|
|
89
|
-
return t === Symbol.asyncIterator &&
|
|
88
|
+
function Ee(e, t) {
|
|
89
|
+
return t === Symbol.asyncIterator && ae(e, [IDBIndex, IDBObjectStore, IDBCursor]) || t === "iterate" && ae(e, [IDBIndex, IDBObjectStore]);
|
|
90
90
|
}
|
|
91
|
-
|
|
92
|
-
const
|
|
91
|
+
xe((e) => ({ ...e, get: (t, n, a) => Ee(t, n) ? ht : e.get(t, n, a), has: (t, n) => Ee(t, n) || e.has(t, n) }));
|
|
92
|
+
const It = "sprigReplayIframeLoaded", vt = "sprigReplayIframeSettings", St = "sprigReplayIframeTakeFullSnapshot", Dt = "sprigReplayTeardown", ye = [], Be = new class {
|
|
93
93
|
constructor(e) {
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
X(this, "awaitingResolvers", []);
|
|
95
|
+
X(this, "activeCount", 0);
|
|
96
96
|
this.capacity = e;
|
|
97
97
|
}
|
|
98
98
|
async acquire() {
|
|
@@ -115,18 +115,18 @@ const ht = "sprigReplayIframeLoaded", It = "sprigReplayIframeSettings", vt = "sp
|
|
|
115
115
|
setLimit(e) {
|
|
116
116
|
this.capacity = e;
|
|
117
117
|
}
|
|
118
|
-
}(2),
|
|
119
|
-
var
|
|
118
|
+
}(2), Me = async ({ apiUrl: e, surveyId: t, uploadId: n, etags: a, headers: r, responseGroupUuid: o, replayDuration: s, eventDigest: l }, i = !1) => {
|
|
119
|
+
var y;
|
|
120
120
|
if (!i && !n && !a) return void d.error("UploadErr", { isMobile: i, uploadId: n, etags: a });
|
|
121
121
|
d.info("MarkUploadComplete", { surveyId: t });
|
|
122
|
-
const
|
|
123
|
-
return d.info("MarkUploadDone", { surveyId: t }),
|
|
124
|
-
},
|
|
122
|
+
const u = await z(`${e}/sdk/1/completeSessionReplay`, { method: "POST", body: JSON.stringify({ etags: a, uploadId: n, responseGroupUuid: o, surveyId: t, replayDuration: s, eventDigest: l, userAgent: (y = window == null ? void 0 : window.navigator) == null ? void 0 : y.userAgent }), headers: r, shouldRetryRequest: !0 });
|
|
123
|
+
return d.info("MarkUploadDone", { surveyId: t }), u;
|
|
124
|
+
}, bt = (e) => {
|
|
125
125
|
if (e instanceof Attr) return null;
|
|
126
126
|
let t = 1;
|
|
127
127
|
for (let n = e.previousSibling; n; n = n.previousSibling) n.nodeName === e.nodeName && ++t;
|
|
128
128
|
return t;
|
|
129
|
-
},
|
|
129
|
+
}, Ae = (e) => {
|
|
130
130
|
if (e === null) return "";
|
|
131
131
|
const t = [];
|
|
132
132
|
if (e instanceof Document) return "/";
|
|
@@ -148,12 +148,12 @@ const ht = "sprigReplayIframeLoaded", It = "sprigReplayIframeSettings", vt = "sp
|
|
|
148
148
|
case Node.ELEMENT_NODE:
|
|
149
149
|
a.name = n.nodeName;
|
|
150
150
|
}
|
|
151
|
-
a.position =
|
|
151
|
+
a.position = bt(n);
|
|
152
152
|
}
|
|
153
153
|
return "/" + t.reverse().map((n) => n.position !== null ? `/${n.name}[${n.position}]` : `/${n.name}`).join("");
|
|
154
|
-
},
|
|
154
|
+
}, fe = (e) => e && e.trim().substring(0, 500).replace(/\s\s+/g, " ").replace(/\r?\n|\r/g, " ").substring(0, 250), C = { capture: !0, passive: !0 }, Et = ["a", "button", "input", "option", "li", "link"], Rt = ["Escape", "Enter", "Backspace", "F5", "Tab"];
|
|
155
155
|
let K = !1, b = null, j = null;
|
|
156
|
-
const
|
|
156
|
+
const Re = (e) => {
|
|
157
157
|
var n;
|
|
158
158
|
if (((n = e.tagName) == null ? void 0 : n.toLowerCase()) === "html") return { element: "html" };
|
|
159
159
|
const t = {};
|
|
@@ -165,27 +165,27 @@ const be = (e) => {
|
|
|
165
165
|
}, Ct = (e) => {
|
|
166
166
|
var a;
|
|
167
167
|
if (!e) return {};
|
|
168
|
-
const t = { ...
|
|
169
|
-
if (n &&
|
|
170
|
-
const r =
|
|
168
|
+
const t = { ...Re(e) }, n = e.parentElement;
|
|
169
|
+
if (n && Et.includes((a = n.tagName) == null ? void 0 : a.toLowerCase())) {
|
|
170
|
+
const r = Re(n);
|
|
171
171
|
Object.assign(t, r);
|
|
172
172
|
}
|
|
173
173
|
return t;
|
|
174
|
-
},
|
|
175
|
-
var r,
|
|
174
|
+
}, _e = (e, t) => {
|
|
175
|
+
var r, o;
|
|
176
176
|
let n = t.target;
|
|
177
177
|
var a;
|
|
178
|
-
t.target === ((r = window.document) == null ? void 0 : r.body) && window.Sprig.pointerDownTarget && (n = window.Sprig.pointerDownTarget), a = { x: t.x, y: t.y, type: e, elementAttributes: Ct(n), windowHeight: window.innerHeight, windowWidth: window.innerWidth, ...n instanceof HTMLElement ? { rect: n == null ? void 0 : n.getBoundingClientRect(), xPath:
|
|
179
|
-
},
|
|
178
|
+
t.target === ((r = window.document) == null ? void 0 : r.body) && window.Sprig.pointerDownTarget && (n = window.Sprig.pointerDownTarget), a = { x: t.x, y: t.y, type: e, elementAttributes: Ct(n), windowHeight: window.innerHeight, windowWidth: window.innerWidth, ...n instanceof HTMLElement ? { rect: n == null ? void 0 : n.getBoundingClientRect(), xPath: Ae(n) } : {} }, (o = a == null ? void 0 : a.elementAttributes) != null && o.text && (a.elementAttributes.text = fe(a.elementAttributes.text)), b == null || b("Sprig_Click", a);
|
|
179
|
+
}, Ne = (e) => {
|
|
180
180
|
var t;
|
|
181
|
-
|
|
182
|
-
},
|
|
181
|
+
Rt.includes(e.key) && (t = { key: e.key }, b == null || b("Sprig_Keystroke", t));
|
|
182
|
+
}, Pt = () => {
|
|
183
183
|
var e;
|
|
184
184
|
window.performance.getEntriesByType("navigation").map((t) => t.type).includes("reload") && (e = { url: window.location.href, currentPageTitle: document.title }, b == null || b("Sprig_Refresh", e));
|
|
185
|
-
},
|
|
185
|
+
}, kt = () => {
|
|
186
186
|
var e;
|
|
187
|
-
window.performance.getEntriesByType("navigation").map((t) => t.type).includes("back_forward") && ((e = { curUrl: window.location.href, fromUrl: document.referrer, currentPageTitle: document.title }).currentPageTitle && (e.currentPageTitle =
|
|
188
|
-
},
|
|
187
|
+
window.performance.getEntriesByType("navigation").map((t) => t.type).includes("back_forward") && ((e = { curUrl: window.location.href, fromUrl: document.referrer, currentPageTitle: document.title }).currentPageTitle && (e.currentPageTitle = fe(e.currentPageTitle)), b == null || b("Sprig_BackForward", e));
|
|
188
|
+
}, Le = /* @__PURE__ */ ((e, t) => {
|
|
189
189
|
let n;
|
|
190
190
|
return (a) => {
|
|
191
191
|
clearTimeout(n), n = window.setTimeout(() => e(a), t);
|
|
@@ -193,90 +193,90 @@ const be = (e) => {
|
|
|
193
193
|
})((e) => {
|
|
194
194
|
if (!(e.target instanceof HTMLElement || e.target instanceof Document)) return;
|
|
195
195
|
let t = e.target;
|
|
196
|
-
"scrollTop" in t || (t = t.documentElement), j == null || j({ xPath:
|
|
197
|
-
}, 750),
|
|
198
|
-
var
|
|
199
|
-
const
|
|
200
|
-
e.button === 2 &&
|
|
201
|
-
},
|
|
196
|
+
"scrollTop" in t || (t = t.documentElement), j == null || j({ xPath: Ae(t), x: t.scrollLeft, y: t.scrollTop, elementAttributes: { targetScrollWidth: t.scrollWidth, targetClientWidth: t.clientWidth, targetScrollHeight: t.scrollHeight, targetClientHeight: t.clientHeight } });
|
|
197
|
+
}, 750), Oe = (Ce = "left_click", (e) => _e(Ce, e));
|
|
198
|
+
var Ce;
|
|
199
|
+
const Fe = (e) => {
|
|
200
|
+
e.button === 2 && _e("right_click", e);
|
|
201
|
+
}, He = (e) => {
|
|
202
202
|
window.Sprig && (window.Sprig.pointerDownTarget = e.target);
|
|
203
203
|
}, g = { isRecording: !1, scrollEventUuids: {}, stopRecording: () => {
|
|
204
|
-
} },
|
|
205
|
-
const e =
|
|
206
|
-
if (e) return d.info("SessionIDFound", { savedSessionId: e }),
|
|
207
|
-
const t =
|
|
204
|
+
} }, je = () => window.indexedDB && window.IDBKeyRange && window.CompressionStream, I = (() => {
|
|
205
|
+
const e = m.getItem("sprig.sessionId");
|
|
206
|
+
if (e) return d.info("SessionIDFound", { savedSessionId: e }), m.removeItem("sprig.sessionId"), e;
|
|
207
|
+
const t = q();
|
|
208
208
|
return d.info("GeneratedSessionID", { uuid: t }), t;
|
|
209
|
-
})(),
|
|
210
|
-
|
|
211
|
-
},
|
|
209
|
+
})(), le = () => {
|
|
210
|
+
m.setItem("sprig.disableReplayRecording", "disabled");
|
|
211
|
+
}, P = () => !!m.getItem("sprig.disableReplayRecording"), W = () => !!m.getItem("sprig.isReplayPaused");
|
|
212
212
|
window.addEventListener("beforeunload", () => {
|
|
213
|
-
d.info("BeforeUnload", { sessionId: I }),
|
|
213
|
+
d.info("BeforeUnload", { sessionId: I }), m.setItem("sprig.sessionId", I);
|
|
214
214
|
});
|
|
215
|
-
const
|
|
215
|
+
const x = (e, t) => {
|
|
216
216
|
var n, a;
|
|
217
|
-
if (!
|
|
217
|
+
if (!P() && g.isRecording && !W()) try {
|
|
218
218
|
(a = (n = window.rrwebRecord) == null ? void 0 : n.addCustomEvent) == null || a.call(n, e, t);
|
|
219
219
|
} catch (r) {
|
|
220
|
-
|
|
220
|
+
Q("Error recording custom event", r);
|
|
221
221
|
}
|
|
222
222
|
}, Ut = async (e) => {
|
|
223
223
|
const { x: t, xPath: n, y: a } = e, r = g.scrollEventUuids[n];
|
|
224
224
|
if (r) return D(async () => {
|
|
225
|
-
var
|
|
226
|
-
const
|
|
227
|
-
if (
|
|
228
|
-
const p = JSON.parse(
|
|
229
|
-
if (!h && !
|
|
230
|
-
h && (p.data.payload.x = t),
|
|
231
|
-
} else
|
|
225
|
+
var l, i, u, y;
|
|
226
|
+
const o = await c.openDB(), s = await o.get("events", r);
|
|
227
|
+
if (s != null && s.event) {
|
|
228
|
+
const p = JSON.parse(s.event), h = t > ((i = (l = p.data) == null ? void 0 : l.payload) == null ? void 0 : i.x), w = a > ((y = (u = p.data) == null ? void 0 : u.payload) == null ? void 0 : y.y);
|
|
229
|
+
if (!h && !w) return null;
|
|
230
|
+
h && (p.data.payload.x = t), w && (p.data.payload.y = a), p.data.payload.elementAttributes = e.elementAttributes, s.event = JSON.stringify(p), await o.put("events", s);
|
|
231
|
+
} else x("Sprig_Scroll", e);
|
|
232
232
|
}, "Error updating scroll event");
|
|
233
|
-
|
|
234
|
-
},
|
|
233
|
+
x("Sprig_Scroll", e);
|
|
234
|
+
}, Ve = () => {
|
|
235
235
|
g.stopRecording && (g.stopRecording(), g.stopRecording = void 0), g.isRecording = !1, ["cleanupInterval", "inactivityInterval", "pendingCheckInterval"].forEach((e) => {
|
|
236
236
|
g[e] && (clearInterval(g[e]), g[e] = void 0);
|
|
237
|
-
}), K && (window.removeEventListener("click",
|
|
237
|
+
}), K && (window.removeEventListener("click", Oe, C), window.removeEventListener("pointerdown", He, C), window.removeEventListener("mousedown", Fe, C), window.removeEventListener("keydown", Ne, C), window.removeEventListener("scroll", Le, C), K = !1), ye.forEach((e) => {
|
|
238
238
|
var t;
|
|
239
|
-
(t = e.source) == null || t.postMessage({ type:
|
|
239
|
+
(t = e.source) == null || t.postMessage({ type: Dt }, { targetOrigin: e.origin });
|
|
240
240
|
});
|
|
241
|
-
},
|
|
242
|
-
if (!
|
|
243
|
-
if (
|
|
241
|
+
}, xt = ["did not allow mutations", "called in an invalid security context"], Tt = (e, t, { reportError: n = !0, extraInfo: a = {} }) => {
|
|
242
|
+
if (!P() && t instanceof Error) {
|
|
243
|
+
if (le(), t.name === "VersionError") return d.error("VersionErr", { message: e }), void c.deleteDB();
|
|
244
244
|
((r) => {
|
|
245
245
|
if (!r) return !0;
|
|
246
|
-
for (const
|
|
246
|
+
for (const o of xt) if (r.toLowerCase().includes(o)) return !1;
|
|
247
247
|
return !0;
|
|
248
|
-
})(t == null ? void 0 : t.message) && (n && window.UserLeap.reportError(e, t, a),
|
|
248
|
+
})(t == null ? void 0 : t.message) && (n && window.UserLeap.reportError(e, t, a), c.clearAll());
|
|
249
249
|
}
|
|
250
|
-
},
|
|
251
|
-
|
|
250
|
+
}, Q = (e, t, { reportError: n } = { reportError: !0 }) => {
|
|
251
|
+
Ve(), d.error("ReplayErr", { code: t.code, name: t.name }), Tt(e, t, { reportError: n });
|
|
252
252
|
}, D = async (e, t) => {
|
|
253
253
|
try {
|
|
254
254
|
return await e();
|
|
255
255
|
} catch (n) {
|
|
256
|
-
|
|
256
|
+
Q(t, n);
|
|
257
257
|
}
|
|
258
|
-
},
|
|
258
|
+
}, ue = () => {
|
|
259
259
|
g.isRecording && (D(() => {
|
|
260
260
|
var e, t;
|
|
261
261
|
return (t = (e = window.rrwebRecord) == null ? void 0 : e.takeFullSnapshot) == null ? void 0 : t.call(e, !0);
|
|
262
|
-
}, "Error recording full snapshot"),
|
|
262
|
+
}, "Error recording full snapshot"), ye.forEach((e) => {
|
|
263
263
|
var t;
|
|
264
|
-
(t = e.source) == null || t.postMessage({ type:
|
|
264
|
+
(t = e.source) == null || t.postMessage({ type: St }, { targetOrigin: e.origin });
|
|
265
265
|
}));
|
|
266
266
|
};
|
|
267
|
-
|
|
268
|
-
const
|
|
267
|
+
(async () => je() && Promise.allSettled([ie("replayStorage"), ie("sprig.replay")]))();
|
|
268
|
+
const c = new class {
|
|
269
269
|
openDB() {
|
|
270
|
-
return function(e, t, { blocked: n, upgrade: a, blocking: r, terminated:
|
|
271
|
-
const
|
|
272
|
-
return a && (
|
|
273
|
-
a(
|
|
274
|
-
}), n && (
|
|
275
|
-
|
|
270
|
+
return function(e, t, { blocked: n, upgrade: a, blocking: r, terminated: o } = {}) {
|
|
271
|
+
const s = indexedDB.open(e, t), l = M(s);
|
|
272
|
+
return a && (s.onupgradeneeded = (i) => {
|
|
273
|
+
a(M(s.result), i.oldVersion, i.newVersion, M(s.transaction), i);
|
|
274
|
+
}), n && (s.onblocked = (i) => n(i.oldVersion, i.newVersion, i)), l.then((i) => {
|
|
275
|
+
o && (i.onclose = () => o()), r && (i.onversionchange = (u) => r(u.oldVersion, u.newVersion, u));
|
|
276
276
|
}).catch(() => {
|
|
277
|
-
}),
|
|
277
|
+
}), l;
|
|
278
278
|
}("sprigReplay", 1, { upgrade: (e, t, n) => {
|
|
279
|
-
if (n === 0 &&
|
|
279
|
+
if (n === 0 && m.setItem("sprig.pendingCount", "0"), !e.objectStoreNames.contains("events")) {
|
|
280
280
|
const a = e.createObjectStore("events", { keyPath: "uuid" });
|
|
281
281
|
a.createIndex("sessionId", "sessionId"), a.createIndex("timestamp", "timestamp"), a.createIndex("[sessionId+timestamp]", ["sessionId", "timestamp"]);
|
|
282
282
|
}
|
|
@@ -290,8 +290,11 @@ const u = new class {
|
|
|
290
290
|
}
|
|
291
291
|
} });
|
|
292
292
|
}
|
|
293
|
-
deleteDB() {
|
|
294
|
-
|
|
293
|
+
async deleteDB() {
|
|
294
|
+
try {
|
|
295
|
+
await ie("sprigReplay");
|
|
296
|
+
} catch {
|
|
297
|
+
}
|
|
295
298
|
}
|
|
296
299
|
async bulkAdd(e, t) {
|
|
297
300
|
const n = (await this.openDB()).transaction(e, "readwrite");
|
|
@@ -303,7 +306,7 @@ const u = new class {
|
|
|
303
306
|
}
|
|
304
307
|
async deleteBySessionId(e, t) {
|
|
305
308
|
const n = IDBKeyRange.only(t), a = (await this.openDB()).transaction(e, "readwrite"), r = a.store.index("sessionId");
|
|
306
|
-
for await (const
|
|
309
|
+
for await (const o of r.iterate(n)) await o.delete();
|
|
307
310
|
await a.done;
|
|
308
311
|
}
|
|
309
312
|
async updatePartial(e, t, n) {
|
|
@@ -311,8 +314,8 @@ const u = new class {
|
|
|
311
314
|
r && await a.store.put({ ...r, ...n }), await a.done;
|
|
312
315
|
}
|
|
313
316
|
async deleteRowsBefore(e, t, n = () => !0) {
|
|
314
|
-
const a = IDBKeyRange.upperBound(t, !0), r = (await this.openDB()).transaction(e, "readwrite"),
|
|
315
|
-
for await (const
|
|
317
|
+
const a = IDBKeyRange.upperBound(t, !0), r = (await this.openDB()).transaction(e, "readwrite"), o = r.store.index("timestamp");
|
|
318
|
+
for await (const s of o.iterate(a)) n(s.value) && await s.delete();
|
|
316
319
|
await r.done;
|
|
317
320
|
}
|
|
318
321
|
async getEventsBetween(e, t = Date.now()) {
|
|
@@ -321,19 +324,19 @@ const u = new class {
|
|
|
321
324
|
return (await this.openDB()).getAllFromIndex("events", "[sessionId+timestamp]", n);
|
|
322
325
|
}
|
|
323
326
|
async updateEventsExpiredAt(e, t, n = 30) {
|
|
324
|
-
const a = /* @__PURE__ */ new Date(), r = a.setMinutes(a.getMinutes() + (n ?? 30)),
|
|
325
|
-
for await (const i of
|
|
326
|
-
await
|
|
327
|
+
const a = /* @__PURE__ */ new Date(), r = a.setMinutes(a.getMinutes() + (n ?? 30)), o = (await this.openDB()).transaction("events", "readwrite"), s = o.store.index("[sessionId+timestamp]"), l = IDBKeyRange.bound([I, e], [I, t], !1, !0);
|
|
328
|
+
for await (const i of s.iterate(l)) await i.update({ ...i.value, expiredAt: r });
|
|
329
|
+
await o.done;
|
|
327
330
|
}
|
|
328
331
|
async deleteChunkUploads(e, t) {
|
|
329
332
|
const n = IDBKeyRange.only([t, e]), a = (await this.openDB()).transaction("chunkUploads", "readwrite");
|
|
330
|
-
let
|
|
331
|
-
for (;
|
|
333
|
+
let o = await a.store.index("[uploadId+status]").openCursor(n);
|
|
334
|
+
for (; o; ) o.delete(), o = await o.continue();
|
|
332
335
|
await a.done;
|
|
333
336
|
}
|
|
334
337
|
async getChunkUploadsByStatus({ sessionId: e, status: t, uploadId: n }) {
|
|
335
|
-
const a = (await this.openDB()).transaction("chunkUploads", "readonly"), r = n ? a.store.index("[uploadId+status]") : a.store.index("[sessionId+status]"),
|
|
336
|
-
return r.getAll(
|
|
338
|
+
const a = (await this.openDB()).transaction("chunkUploads", "readonly"), r = n ? a.store.index("[uploadId+status]") : a.store.index("[sessionId+status]"), o = n ? IDBKeyRange.only([n, t]) : IDBKeyRange.only([e, t]);
|
|
339
|
+
return r.getAll(o);
|
|
337
340
|
}
|
|
338
341
|
async getPendingCaptures(e = {}) {
|
|
339
342
|
return (await (await this.openDB()).getAllFromIndex("pendingCaptures", "sessionId", I)).filter((n) => !e.beforePresent || n.targetTimestamp < Date.now()).filter((n) => !e.isBeforeType || n.captureParams.replayParams.replayDurationType === "before").filter((n) => !e.isHeatmap || (n.captureParams.isHeatmap ?? !1));
|
|
@@ -347,43 +350,43 @@ const u = new class {
|
|
|
347
350
|
await t.done;
|
|
348
351
|
}
|
|
349
352
|
async markPendingHeatmapsReady(e) {
|
|
350
|
-
if (parseInt(
|
|
353
|
+
if (parseInt(m.getItem("sprig.pendingCount") ?? "0") === 0) return null;
|
|
351
354
|
const t = Date.now(), n = (await this.openDB()).transaction("pendingCaptures", "readwrite"), a = n.store.index("sessionId");
|
|
352
355
|
for await (const r of a.iterate(I)) {
|
|
353
|
-
const
|
|
354
|
-
!
|
|
356
|
+
const o = r.value;
|
|
357
|
+
!o.captureParams.isHeatmap || e && !e.includes(o.uuid) || await r.update({ ...o, targetTimestamp: t, captureParams: { ...o.captureParams, triggerTimestamp: t, replayParams: { ...o.captureParams.replayParams, replayDurationSeconds: Math.floor((t - o.timestamp) / 1e3) } } });
|
|
355
358
|
}
|
|
356
359
|
await n.done;
|
|
357
360
|
}
|
|
358
|
-
}(),
|
|
359
|
-
let F,
|
|
360
|
-
const O = () => G && !L && Date.now() <=
|
|
361
|
-
G && !a || (
|
|
362
|
-
},
|
|
363
|
-
if (!O()) return void window.clearInterval(
|
|
364
|
-
if (
|
|
365
|
-
const e =
|
|
361
|
+
}(), T = [];
|
|
362
|
+
let F, Ge, J, $e, V, Ke, _ = [], L = !1, N = 0, G = !1, We = !1, he = [], te = !1;
|
|
363
|
+
const O = () => G && !L && Date.now() <= J, Bt = ({ apiUrl: e, config: t, triggerSnapshot: n, forceInit: a = !1 }) => {
|
|
364
|
+
G && !a || (m.isStorageAvailable ? (_ = [], he.splice(0), T.splice(0), N = 0, V = n, Ge = e, F = { responseGroupUuid: t.responseGroupUuid, surveyId: t.surveyId, userAgent: t.userAgent, sdkVersion: t.sdkVersion }, $e = t.maxDurationSeconds, Nt(), G || (Ke = window.setInterval(_t, 500)), G = !0) : L = !0);
|
|
365
|
+
}, Mt = [U.Drag, U.Input, U.MediaInteraction, U.MouseInteraction, U.MouseMove, U.Scroll, U.Selection, U.TouchMove], At = (e) => e.type === B.Custom || e.type === B.IncrementalSnapshot && Mt.includes(e.data.source), Ie = (e) => e.some(At), _t = async () => {
|
|
366
|
+
if (!O()) return void window.clearInterval(Ke);
|
|
367
|
+
if (Je(), !Ie(T)) return;
|
|
368
|
+
const e = T[0].timestamp;
|
|
366
369
|
Date.now() - e > 35e3 && (V == null || V());
|
|
367
|
-
},
|
|
368
|
-
if (_.length ||
|
|
369
|
-
|
|
370
|
-
const e = await
|
|
370
|
+
}, Je = async () => {
|
|
371
|
+
if (_.length || te) return;
|
|
372
|
+
te = !0;
|
|
373
|
+
const e = await Ot();
|
|
371
374
|
if (!e) return void (L = !0);
|
|
372
|
-
|
|
373
|
-
},
|
|
374
|
-
const e =
|
|
375
|
+
he.splice(0, e.length).forEach((t) => t(e.shift())), e.forEach((t) => _.push(t)), te = !1;
|
|
376
|
+
}, Nt = () => {
|
|
377
|
+
const e = m.getItem("sprig.alwayson.info");
|
|
375
378
|
if (e) {
|
|
376
379
|
d.info("Read stored session state", e);
|
|
377
380
|
const t = JSON.parse(e);
|
|
378
|
-
L = t.disabled, F = t.metadata, _ = t.uploadUrls, N = t.currentIndex,
|
|
379
|
-
} else
|
|
380
|
-
},
|
|
381
|
-
const t = Date.now(), n = (await
|
|
382
|
-
if (!
|
|
383
|
-
|
|
384
|
-
const a = await
|
|
385
|
-
a && await
|
|
386
|
-
},
|
|
381
|
+
L = t.disabled, F = t.metadata, _ = t.uploadUrls, N = t.currentIndex, J = t.expirationTimestamp, t.pendingEventTimestamp && (d.info(`Uploading with pending timestamp: ${t.pendingEventTimestamp}`), Lt(t.pendingEventTimestamp));
|
|
382
|
+
} else J = 1e3 * $e + Date.now();
|
|
383
|
+
}, Lt = async (e) => {
|
|
384
|
+
const t = Date.now(), n = (await c.getEventsBetween(e, t)).map((r) => JSON.parse(r.event));
|
|
385
|
+
if (!Ie(n)) return;
|
|
386
|
+
Xe(n);
|
|
387
|
+
const a = await Qe();
|
|
388
|
+
a && await qe(a, n);
|
|
389
|
+
}, ze = async (e, t) => {
|
|
387
390
|
try {
|
|
388
391
|
const n = await e();
|
|
389
392
|
if (!n.ok) throw new Error(`Error ${t}`);
|
|
@@ -391,300 +394,304 @@ const O = () => G && !L && Date.now() <= W, Bt = ({ apiUrl: e, config: t, trigge
|
|
|
391
394
|
} catch {
|
|
392
395
|
L = !0;
|
|
393
396
|
}
|
|
394
|
-
},
|
|
397
|
+
}, qe = async (e, t) => {
|
|
395
398
|
if (!O() || !e) return;
|
|
396
399
|
const n = await (async (a) => {
|
|
397
|
-
const r = new TextEncoder(),
|
|
398
|
-
return
|
|
400
|
+
const r = new TextEncoder(), o = new CompressionStream("gzip"), s = o.writable.getWriter(), l = r.encode(JSON.stringify(a));
|
|
401
|
+
return s.write(l), s.close(), new Uint8Array(await new Response(o.readable).arrayBuffer());
|
|
399
402
|
})(t);
|
|
400
|
-
d.info("Uploading always-on events with presigned url"), await
|
|
401
|
-
},
|
|
403
|
+
d.info("Uploading always-on events with presigned url"), await ze(() => z(e, { body: n, method: "PUT" }), "uploading always-on with presigned url");
|
|
404
|
+
}, Ot = async () => {
|
|
402
405
|
if (!O()) return;
|
|
403
406
|
const { surveyId: e, responseGroupUuid: t } = F, n = { responseGroupUuid: t, surveyId: e, index: N + 1 };
|
|
404
407
|
d.info("Fetching always-on upload urls", n);
|
|
405
|
-
const a = await
|
|
408
|
+
const a = await ze(() => z(`${Ge}/sdk/1/replayUrls`, { method: "POST", body: JSON.stringify(n), headers: lt(window.UserLeap) }), "fetching always-on signed urls");
|
|
406
409
|
if (!a) return;
|
|
407
410
|
const r = a.json.signedUrls;
|
|
408
411
|
return d.info("Fetched more always-on upload urls", { body: n, urls: r }), r;
|
|
409
|
-
},
|
|
412
|
+
}, Qe = async () => {
|
|
410
413
|
if (_.length) return _.shift();
|
|
411
414
|
const e = new Promise((t) => {
|
|
412
|
-
|
|
415
|
+
he.push(t);
|
|
413
416
|
});
|
|
414
|
-
return
|
|
415
|
-
},
|
|
416
|
-
var r,
|
|
417
|
-
const t = e.length ? e[e.length - 1].timestamp : Date.now(), n = N, a = ((
|
|
417
|
+
return Je(), e;
|
|
418
|
+
}, Xe = (e) => {
|
|
419
|
+
var r, o, s;
|
|
420
|
+
const t = e.length ? e[e.length - 1].timestamp : Date.now(), n = N, a = ((o = (r = window.UserLeap) == null ? void 0 : r.config) == null ? void 0 : o.customMetadata) ?? ((s = window.__cfg) == null ? void 0 : s.customMetadata);
|
|
418
421
|
N++, e.push({ timestamp: t, type: B.Custom, data: { tag: "Sprig_Meta", payload: { ...F, index: n, visitorId: window.UserLeap.visitorId ?? "", timestamp: t, customMetadata: a } } });
|
|
419
|
-
},
|
|
420
|
-
O() && !
|
|
421
|
-
const n =
|
|
422
|
-
if (!
|
|
423
|
-
d.info("Capturing always-on event array to upload"),
|
|
424
|
-
const a = await
|
|
425
|
-
a && await
|
|
426
|
-
})(),
|
|
422
|
+
}, Ft = (e, t) => {
|
|
423
|
+
O() && !We && (e || T.length) && (e && T.length && (async () => {
|
|
424
|
+
const n = T.splice(0);
|
|
425
|
+
if (!Ie(n)) return;
|
|
426
|
+
d.info("Capturing always-on event array to upload"), Xe(n);
|
|
427
|
+
const a = await Qe();
|
|
428
|
+
a && await qe(a, n);
|
|
429
|
+
})(), T.push(t));
|
|
427
430
|
};
|
|
428
431
|
window.addEventListener("beforeunload", async () => {
|
|
429
|
-
|
|
432
|
+
We = !0, O() && (d.info("Always On handle page unload"), (() => {
|
|
430
433
|
let e;
|
|
431
|
-
|
|
432
|
-
const t = { disabled: L, metadata: F, uploadUrls: _, currentIndex: N, pendingEventTimestamp: e, expirationTimestamp:
|
|
433
|
-
d.info("Storing session state on unload", t),
|
|
434
|
+
T.length && (e = T[0].timestamp);
|
|
435
|
+
const t = { disabled: L, metadata: F, uploadUrls: _, currentIndex: N, pendingEventTimestamp: e, expirationTimestamp: J };
|
|
436
|
+
d.info("Storing session state on unload", t), m.setItem("sprig.alwayson.info", JSON.stringify(t));
|
|
434
437
|
})());
|
|
435
438
|
});
|
|
436
|
-
const
|
|
439
|
+
const Ze = async (e, t) => {
|
|
437
440
|
const n = performance.now();
|
|
438
441
|
let a;
|
|
439
442
|
try {
|
|
440
443
|
a = await e();
|
|
441
444
|
} finally {
|
|
442
445
|
const r = performance.now() - n;
|
|
443
|
-
let
|
|
444
|
-
|
|
446
|
+
let o = ke[t];
|
|
447
|
+
o || (o = Ue(t)), o.report(r / 1e3);
|
|
445
448
|
}
|
|
446
449
|
return a;
|
|
447
|
-
},
|
|
450
|
+
}, Ye = (e, t) => {
|
|
448
451
|
const n = performance.now();
|
|
449
452
|
try {
|
|
450
453
|
e();
|
|
451
454
|
} finally {
|
|
452
455
|
const a = performance.now() - n;
|
|
453
456
|
let r = ke[t];
|
|
454
|
-
r || (r =
|
|
457
|
+
r || (r = Ue(t)), r.report(a / 1e3);
|
|
455
458
|
}
|
|
456
459
|
};
|
|
457
|
-
let
|
|
458
|
-
const
|
|
460
|
+
let et = 5e3, ce = 6e4, pe = 0, A, ge = !1, me = [];
|
|
461
|
+
const Ht = (e) => {
|
|
459
462
|
var t, n, a, r;
|
|
460
463
|
if ((t = e.event) != null && t.includes("Sprig_Scroll")) {
|
|
461
|
-
const
|
|
462
|
-
if (!
|
|
463
|
-
g.scrollEventUuids[
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
},
|
|
467
|
-
|
|
468
|
-
if (
|
|
469
|
-
const e =
|
|
470
|
-
|
|
464
|
+
const o = (r = (a = (n = JSON.parse(e.event)) == null ? void 0 : n.data) == null ? void 0 : a.payload) == null ? void 0 : r.xPath;
|
|
465
|
+
if (!o) return;
|
|
466
|
+
g.scrollEventUuids[o] = e.uuid;
|
|
467
|
+
}
|
|
468
|
+
me.push(e), ge || jt();
|
|
469
|
+
}, jt = () => {
|
|
470
|
+
ge = !0, setTimeout(async () => {
|
|
471
|
+
if (P() || W()) return;
|
|
472
|
+
const e = me;
|
|
473
|
+
me = [], ge = !1, Ye(async () => {
|
|
471
474
|
await (async (t) => {
|
|
472
475
|
const n = t.map((a) => ({ ...a, sessionId: a.sessionId ?? I }));
|
|
473
|
-
if (n.length !== 0) return D(() =>
|
|
476
|
+
if (n.length !== 0) return D(() => c.bulkAdd("events", n), "Error storing replay events");
|
|
474
477
|
})(e);
|
|
475
478
|
}, "sdk_replay_add_event_batch_seconds");
|
|
476
479
|
}, 500);
|
|
477
|
-
},
|
|
480
|
+
}, Vt = (e, t, n) => {
|
|
478
481
|
g.cleanupInterval = window.setInterval(() => {
|
|
479
482
|
const a = Date.now();
|
|
480
|
-
|
|
481
|
-
|
|
483
|
+
Ze(() => D(async () => {
|
|
484
|
+
P() || await Promise.all([c.deleteRowsBefore("events", a - 1e3 * e, (r) => r.expiredAt === void 0 || r.expiredAt < a - 1e3 * e), c.deleteRowsBefore("chunkUploads", a - 1e3 * t), c.deleteRowsBefore("pendingCaptures", a - 1e3 * n, (r) => !r.canUpload)]);
|
|
482
485
|
}, "Error deleting table rows"), "sdk_replay_cleanup_seconds"), d.debug("CleanupComplete");
|
|
483
486
|
}, 3e4);
|
|
484
|
-
},
|
|
487
|
+
}, Gt = () => {
|
|
485
488
|
g.pendingCheckInterval = window.setInterval(async () => {
|
|
486
489
|
D(async () => {
|
|
487
|
-
await
|
|
490
|
+
await we();
|
|
488
491
|
}, "Error initiating pending captures");
|
|
489
492
|
}, 5e3);
|
|
490
493
|
};
|
|
491
|
-
let
|
|
492
|
-
const
|
|
493
|
-
if (!
|
|
494
|
-
|
|
495
|
-
const t = parseInt(
|
|
494
|
+
let ne = !1;
|
|
495
|
+
const we = async (e = !1) => {
|
|
496
|
+
if (!ne) try {
|
|
497
|
+
ne = !0;
|
|
498
|
+
const t = parseInt(A ?? "0");
|
|
496
499
|
if (t === 0) return;
|
|
497
|
-
const n = await
|
|
498
|
-
await Promise.all(n.map(async (r) => (await a.delete("pendingCaptures", r.uuid),
|
|
500
|
+
const n = await c.getPendingCaptures({ beforePresent: !0, isBeforeType: e }), a = await c.openDB();
|
|
501
|
+
await Promise.all(n.map(async (r) => (await a.delete("pendingCaptures", r.uuid), at(r.captureParams, r.canUpload)))), A = (t - n.length).toString(), m.setItem("sprig.pendingCount", A);
|
|
499
502
|
} finally {
|
|
500
|
-
|
|
503
|
+
ne = !1;
|
|
501
504
|
}
|
|
502
|
-
},
|
|
503
|
-
const
|
|
504
|
-
if (!(
|
|
505
|
+
}, $t = async (e, t, n, a, r) => {
|
|
506
|
+
const o = Math.min(e + r, n), s = await Ze(() => c.getEventsBetween(e, o), "sdk_replay_get_events_between_seconds");
|
|
507
|
+
if (!(s != null && s.length)) return d.debug("NoEventsFound"), { validStartFound: a, events: [] };
|
|
505
508
|
if (!a) {
|
|
506
509
|
d.debug("ValidStartSearch");
|
|
507
|
-
let
|
|
508
|
-
return
|
|
510
|
+
let l = -1;
|
|
511
|
+
return s == null || s.forEach((i, u) => {
|
|
509
512
|
if (!i.isValidStart) return;
|
|
510
|
-
const
|
|
511
|
-
(
|
|
512
|
-
}),
|
|
513
|
-
}
|
|
514
|
-
return { validStartFound: a, events:
|
|
515
|
-
},
|
|
516
|
-
const n = await (async (a) =>
|
|
517
|
-
var
|
|
513
|
+
const y = i.timestamp <= t;
|
|
514
|
+
(l < 0 || y) && (l = u);
|
|
515
|
+
}), l < 0 ? (d.debug("ValidStartNotFound"), { validStartFound: a, events: [] }) : { validStartFound: !0, events: s == null ? void 0 : s.slice(l) };
|
|
516
|
+
}
|
|
517
|
+
return { validStartFound: a, events: s };
|
|
518
|
+
}, tt = (e) => Promise.all(e.map(async (t) => {
|
|
519
|
+
const n = await (async (a) => Be.execute(async () => {
|
|
520
|
+
var s;
|
|
518
521
|
d.info("UploadChunkStart", { chunkIndex: a.chunkIndex, surveyId: a.surveyId });
|
|
519
|
-
const r = await
|
|
522
|
+
const r = await z(a.uploadUrl, { body: a.data, method: "PUT" });
|
|
520
523
|
d.http("UploadChunkEnd", { url: a.uploadUrl, method: "PUT", status_code: r.status, reason: r.statusText ?? "OK", chunkIndex: a.chunkIndex, surveyId: a.surveyId });
|
|
521
|
-
const
|
|
522
|
-
if (!
|
|
523
|
-
return
|
|
524
|
+
const o = (s = r.headers) == null ? void 0 : s.get("ETag");
|
|
525
|
+
if (!o) throw new Error(`Upload response did not include etag for upload ${a.uploadId}, part ${a.chunkIndex}`);
|
|
526
|
+
return o;
|
|
524
527
|
}))(t);
|
|
525
|
-
return await
|
|
526
|
-
})),
|
|
527
|
-
const t = await
|
|
528
|
+
return await c.updatePartial("chunkUploads", t.uuid, { data: null, etag: n, status: "UploadComplete" }), t.uploadId;
|
|
529
|
+
})), nt = async (e) => {
|
|
530
|
+
const t = await c.getChunkUploadsByStatus({ status: "UploadComplete", uploadId: e });
|
|
528
531
|
if (!(t != null && t.length)) return void d.info("NoChunksForUpload", { uploadId: e });
|
|
529
|
-
const n = t.reduce((
|
|
530
|
-
n.sort((
|
|
531
|
-
const a = n.map((
|
|
532
|
-
await
|
|
533
|
-
},
|
|
532
|
+
const n = t.reduce((o, s) => (o.find((l) => l.chunkIndex === s.chunkIndex) || o.push(s), o), []);
|
|
533
|
+
n.sort((o, s) => o.chunkIndex - s.chunkIndex);
|
|
534
|
+
const a = n.map((o) => ({ ETag: o.etag, PartNumber: o.chunkIndex })).filter((o) => o.ETag !== null), r = n[0];
|
|
535
|
+
await Me({ apiUrl: r.apiUrl, surveyId: r.surveyId, uploadId: e, responseGroupUuid: r.responseGroupId, etags: a, headers: r.completeUploadHeaders, replayDuration: r.replayDuration }), await c.deleteChunkUploads("UploadComplete", e);
|
|
536
|
+
}, Kt = () => {
|
|
534
537
|
D(async () => {
|
|
535
|
-
const e = await
|
|
538
|
+
const e = await c.getChunkUploadsByStatus({ sessionId: I, status: "ReadyForUpload" });
|
|
536
539
|
if (!(e != null && e.length)) return;
|
|
537
|
-
const t = await
|
|
540
|
+
const t = await tt(e);
|
|
538
541
|
t != null && t.length && await Promise.all(t.map((n) => {
|
|
539
|
-
if (n) return
|
|
542
|
+
if (n) return nt(n);
|
|
540
543
|
}));
|
|
541
544
|
}, "Error uploading unfinished chunks");
|
|
542
|
-
},
|
|
545
|
+
}, Wt = async (e, t) => {
|
|
543
546
|
const n = t ?? Date.now();
|
|
544
547
|
return (async (a, r) => {
|
|
545
|
-
const
|
|
546
|
-
let
|
|
547
|
-
const
|
|
548
|
-
let
|
|
549
|
-
for (let
|
|
550
|
-
if ({ validStartFound:
|
|
548
|
+
const o = new TextEncoder();
|
|
549
|
+
let s = null;
|
|
550
|
+
const l = new CompressionStream("gzip"), i = l.writable.getWriter();
|
|
551
|
+
let u = !1, y = !1, [p, h] = [0, 0], w = [];
|
|
552
|
+
for (let k = a - 35e3; k < r; k += ce) {
|
|
553
|
+
if ({ validStartFound: y, events: w } = await $t(k, a, r, y, ce), !(w != null && w.length)) {
|
|
551
554
|
d.debug("NoEventsFound");
|
|
552
555
|
continue;
|
|
553
556
|
}
|
|
554
|
-
p === 0 && (p =
|
|
555
|
-
const f =
|
|
557
|
+
p === 0 && (p = w[0].timestamp), h = w[w.length - 1].timestamp;
|
|
558
|
+
const f = w.map((R) => R.event);
|
|
556
559
|
f.push(`{"timestamp":${r}}`);
|
|
557
|
-
const v = `${
|
|
558
|
-
|
|
560
|
+
const v = `${u ? "," : "["}${f}`, S = o.encode(v);
|
|
561
|
+
Ye(() => {
|
|
559
562
|
i.write(S);
|
|
560
|
-
}, "sdk_replay_compression_seconds"),
|
|
563
|
+
}, "sdk_replay_compression_seconds"), u = !0;
|
|
561
564
|
}
|
|
562
|
-
if (h - p <
|
|
563
|
-
const E =
|
|
564
|
-
return i.write(E), i.close(),
|
|
565
|
+
if (h - p < et) return d.debug("ReplayTooShort"), null;
|
|
566
|
+
const E = o.encode("]");
|
|
567
|
+
return i.write(E), i.close(), s = new Uint8Array(await new Response(l.readable).arrayBuffer()), s;
|
|
565
568
|
})(n - e, n);
|
|
566
|
-
},
|
|
567
|
-
const { surveyId: t, responseGroupId: n, visitorId: a, apiUrl: r, completeUploadHeaders:
|
|
569
|
+
}, Pe = async (e) => {
|
|
570
|
+
const { surveyId: t, responseGroupId: n, visitorId: a, apiUrl: r, completeUploadHeaders: o, replayParams: s, triggerTimestamp: l } = e, i = await Wt(1e3 * s.replayDurationSeconds, l);
|
|
568
571
|
if (!(i != null && i.length)) return void d.info("FileDataEmpty", { surveyId: t });
|
|
569
|
-
const
|
|
570
|
-
const E = p.length,
|
|
571
|
-
let
|
|
572
|
-
for (;
|
|
572
|
+
const u = ((p, h, w) => {
|
|
573
|
+
const E = p.length, k = 1024 * h * 1024, f = Math.ceil(E / w), v = Math.max(k, f), S = [];
|
|
574
|
+
let R = 0;
|
|
575
|
+
for (; R < E; ) S.push(p.slice(R, R + v)), R += v;
|
|
573
576
|
return S;
|
|
574
|
-
})(i,
|
|
575
|
-
const
|
|
576
|
-
return await (await
|
|
577
|
+
})(i, s.minimumChunkSizeMb, s.signedUrls.length), y = await Promise.all(u.map(async (p, h) => {
|
|
578
|
+
const w = q(), E = { apiUrl: r, chunkIndex: h + 1, completeUploadHeaders: o, etag: null, responseGroupId: n, status: "ReadyForUpload", surveyId: t, timestamp: l, totalChunks: u.length, data: p, uploadId: s.uploadId, uploadUrl: s.signedUrls[h].url, uuid: w, visitorId: a };
|
|
579
|
+
return await (await c.openDB()).add("chunkUploads", { ...E, sessionId: E.sessionId ?? I }), E;
|
|
577
580
|
}));
|
|
578
581
|
await (async (p, h) => {
|
|
579
|
-
await
|
|
580
|
-
})([
|
|
581
|
-
},
|
|
582
|
-
if (
|
|
583
|
-
const { isHeatmap: n, isStandalone: a, replayParams: r, triggerTimestamp:
|
|
584
|
-
setTimeout(() => H.removeListener(
|
|
585
|
-
r.replayDurationType === "before" ? await
|
|
582
|
+
await tt(h), await Promise.all(p.map((w) => nt(w)));
|
|
583
|
+
})([s.uploadId], y);
|
|
584
|
+
}, at = async (e, t) => {
|
|
585
|
+
if (P()) return d.debug("ReplayDisabled-ScheduleOrCapture");
|
|
586
|
+
const { isHeatmap: n, isStandalone: a, replayParams: r, triggerTimestamp: o, responseGroupId: s } = e, l = async () => {
|
|
587
|
+
setTimeout(() => H.removeListener(Z.QuestionAnswered, l), 0), D(async () => {
|
|
588
|
+
r.replayDurationType === "before" ? await Pe(e) : await c.markPendingCaptureToCanUpload(s);
|
|
586
589
|
}, "Error in schedule/capture callback");
|
|
587
590
|
};
|
|
588
591
|
D(async () => {
|
|
589
592
|
if (r.replayDurationType === "after" || r.replayDurationType === "beforeAndAfter")
|
|
590
|
-
return !a && !n && H.on(
|
|
591
|
-
if (a || n || t) await
|
|
593
|
+
return !a && !n && H.on(Z.QuestionAnswered, l), void await ot(e);
|
|
594
|
+
if (a || n || t) await Pe(e), n && Jt();
|
|
592
595
|
else {
|
|
593
|
-
const i = 35 + r.replayDurationSeconds,
|
|
594
|
-
await
|
|
596
|
+
const i = 35 + r.replayDurationSeconds, u = o - 1e3 * i, y = o;
|
|
597
|
+
await c.updateEventsExpiredAt(u, y, r.expirationTimeLimitMinutes), H.on(Z.QuestionAnswered, l);
|
|
595
598
|
}
|
|
596
599
|
}, "Error in scheduling/capturing replay");
|
|
597
|
-
},
|
|
598
|
-
parseInt(
|
|
599
|
-
},
|
|
600
|
-
|
|
601
|
-
}),
|
|
602
|
-
if (
|
|
603
|
-
const { isHeatmap: t, surveyId: n } = e, a = await
|
|
600
|
+
}, Jt = async () => {
|
|
601
|
+
parseInt(A ?? "0") || m.removeItem("sprig.isCapturingHeatmap"), m.getItem("sprig.teardownAfterCapture") && (Ve(), rt(), m.removeItem("sprig.teardownAfterCapture"));
|
|
602
|
+
}, rt = async () => P() ? d.debug("ReplayDisabled-ClearData") : Promise.all([c.deleteBySessionId("events", I), c.deleteBySessionId("pendingCaptures", I)]).catch((e) => {
|
|
603
|
+
Q("Error clearing user replay data", e);
|
|
604
|
+
}), ot = async (e) => {
|
|
605
|
+
if (P()) return;
|
|
606
|
+
const { isHeatmap: t, surveyId: n } = e, a = await c.getPendingCaptures(), r = a == null ? void 0 : a.filter((i) => i.captureParams.surveyId === n);
|
|
604
607
|
if (r != null && r.length) return void d.info("PendingCaptureExists", { surveyId: n });
|
|
605
|
-
t && (
|
|
608
|
+
t && (ue(), m.setItem("sprig.isCapturingHeatmap", "true"), pe = Date.now(), g.inactivityInterval || (g.inactivityInterval = window.setInterval(() => {
|
|
606
609
|
var i;
|
|
607
|
-
i =
|
|
610
|
+
i = pe, Date.now() - i >= 3e4 && D(() => c.markPendingHeatmapsReady(), "Error in heatmap inactivity");
|
|
608
611
|
}, 1e3)));
|
|
609
|
-
const
|
|
610
|
-
e.replayParams.replayDurationType === "beforeAndAfter" && (
|
|
611
|
-
const
|
|
612
|
-
|
|
613
|
-
},
|
|
614
|
-
|
|
612
|
+
const o = { ...e, replayParams: { ...e.replayParams } };
|
|
613
|
+
e.replayParams.replayDurationType === "beforeAndAfter" && (o.replayParams.replayDurationSeconds *= 2), o.replayParams.replayDurationType = "before";
|
|
614
|
+
const s = e.triggerTimestamp + 1e3 * e.replayParams.replayDurationSeconds;
|
|
615
|
+
o.triggerTimestamp = s, A = (parseInt(A ?? "0") + 1).toString(), m.setItem("sprig.pendingCount", A), await (await c.openDB()).add("pendingCaptures", { canUpload: !1, captureParams: o, sessionId: I, targetTimestamp: s, timestamp: Date.now(), uuid: q() });
|
|
616
|
+
}, zt = Object.freeze(Object.defineProperty({ __proto__: null, RecordEvent: (e) => {
|
|
617
|
+
x("Sprig_TrackEvent", e);
|
|
615
618
|
}, RecordPageView: (e) => {
|
|
616
|
-
e.description && (e.description =
|
|
619
|
+
e.description && (e.description = fe(e.description)), x("Sprig_PageView", e);
|
|
617
620
|
}, RecordSurveyShown: (e) => {
|
|
618
|
-
|
|
621
|
+
x("Sprig_ShowSurvey", e);
|
|
619
622
|
}, _completeSessionReplay: async ({ surveyId: e, responseGroupUuid: t, eventDigest: n, headers: a }) => {
|
|
620
623
|
if (!e || !t) return !1;
|
|
621
|
-
const r = window.UserLeap._API_URL,
|
|
622
|
-
return !(
|
|
623
|
-
}, checkPendingHeatmapsUrl: () =>
|
|
624
|
-
const e = (await
|
|
625
|
-
return d.info("PendingHeatmapsToComplete", { count: e.length }), e.length && (await
|
|
626
|
-
}, "Error marking pending heatmaps ready"), clearUserReplayData:
|
|
627
|
-
if (
|
|
628
|
-
|
|
629
|
-
} }),
|
|
630
|
-
if (a &&
|
|
624
|
+
const r = window.UserLeap._API_URL, o = await Me({ surveyId: e, responseGroupUuid: t, eventDigest: n, apiUrl: r, headers: a }, !0);
|
|
625
|
+
return !(o != null && o.error);
|
|
626
|
+
}, checkPendingHeatmapsUrl: () => P() ? d.debug("ReplayDisabled-PendingHeatmaps") : D(async () => {
|
|
627
|
+
const e = (await c.getPendingCaptures({ isHeatmap: !0 })).map((t) => ({ eventId: t.captureParams.eventId, uuid: t.uuid })).filter(({ eventId: t }) => !dt(t)).map(({ uuid: t }) => t);
|
|
628
|
+
return d.info("PendingHeatmapsToComplete", { count: e.length }), e.length && (await c.markPendingHeatmapsReady(e), d.info("MarkedPendingHeatmapsReady")), e.length;
|
|
629
|
+
}, "Error marking pending heatmaps ready"), clearUserReplayData: rt, disableRecording: Q, initializeReplay: async ({ maxReplayDurationSeconds: e, maxInflightRequests: t = 2, replaySettings: n, teardownAfter: a = !1, apiUrl: r, alwaysOnConfig: o }) => {
|
|
630
|
+
if (o && Bt({ apiUrl: r, config: o, triggerSnapshot: () => {
|
|
631
|
+
ue();
|
|
632
|
+
} }), A = m.getItem("sprig.pendingCount"), g.isRecording) return;
|
|
633
|
+
if (a && m.setItem("sprig.teardownAfterCapture", "true"), P()) return d.debug("ReplayDisabled");
|
|
631
634
|
if (await (async () => {
|
|
632
635
|
var i;
|
|
633
|
-
if (!
|
|
636
|
+
if (!je()) return !0;
|
|
634
637
|
if ((i = window.navigator.storage) != null && i.estimate) try {
|
|
635
|
-
const { quota:
|
|
638
|
+
const { quota: u = 0, usage: y = 0 } = await window.navigator.storage.estimate(), p = (u - y) / 1024 ** 3;
|
|
636
639
|
return d.info("Storage", { availableGb: p }), p < 0.5;
|
|
637
640
|
} catch {
|
|
638
641
|
return !0;
|
|
639
642
|
}
|
|
640
643
|
return !1;
|
|
641
|
-
})()) return d.debug("IDBNotSupported"),
|
|
644
|
+
})()) return d.debug("IDBNotSupported"), le();
|
|
642
645
|
try {
|
|
643
|
-
const i = await
|
|
646
|
+
const i = await c.openDB();
|
|
644
647
|
d.info("DBVersion", { version: i.version });
|
|
645
648
|
} catch (i) {
|
|
646
|
-
return d.error("ReplayOpenErr", { name: i.name }), i.name === "VersionError" &&
|
|
649
|
+
return d.error("ReplayOpenErr", { name: i.name }), i.name === "VersionError" && c.deleteDB(), le();
|
|
647
650
|
}
|
|
648
651
|
D(async () => {
|
|
649
|
-
await
|
|
652
|
+
await we(!0);
|
|
650
653
|
}, "Error uploading ready pending captures");
|
|
651
|
-
const
|
|
652
|
-
if (!
|
|
654
|
+
const s = O() ? 30 : 0, l = Math.max(e ?? 0, s);
|
|
655
|
+
if (!l) return d.debug("MissingDuration");
|
|
653
656
|
d.debug("ReplayInit"), await D(async () => {
|
|
654
657
|
var i;
|
|
655
|
-
n != null && n.minDuration && (
|
|
656
|
-
const
|
|
658
|
+
n != null && n.minDuration && (et = n.minDuration), n != null && n.batchDuration && (ce = n.batchDuration), i = t, Be.setLimit(i), Kt(), Vt(l + 35, 1800, l + 35), Gt();
|
|
659
|
+
const u = window.UserLeap.replayLibraryURL ?? "https://cdn.sprig.com/dependencies/record-2.0.0-alpha.17.min.js";
|
|
657
660
|
if (!window.rrwebRecord) {
|
|
658
661
|
const { record: f } = await import(
|
|
659
662
|
/* webpackIgnore: true */
|
|
660
663
|
/* @vite-ignore */
|
|
661
|
-
|
|
664
|
+
u
|
|
662
665
|
);
|
|
663
666
|
window.rrwebRecord = f;
|
|
664
667
|
}
|
|
665
|
-
const
|
|
666
|
-
if (!
|
|
668
|
+
const y = window.rrwebRecord;
|
|
669
|
+
if (!y) return d.error("RecordScriptFailed");
|
|
667
670
|
let p = !0, h = 0;
|
|
668
|
-
const
|
|
669
|
-
var E,
|
|
670
|
-
g.stopRecording =
|
|
671
|
-
if (f.type === B.Custom && (
|
|
671
|
+
const w = { checkoutEveryNms: 3e4, sampling: { input: "last", scroll: 250, media: 800 }, ...n };
|
|
672
|
+
var E, k;
|
|
673
|
+
g.stopRecording = y({ emit: (f, v) => {
|
|
674
|
+
if (f.type === B.Custom && (pe = Date.now()), P() || W()) return;
|
|
672
675
|
if (v && f.type === B.Meta) h = performance.now();
|
|
673
676
|
else if (v && h && f.type === B.FullSnapshot) {
|
|
674
|
-
const
|
|
675
|
-
|
|
677
|
+
const R = performance.now() - h;
|
|
678
|
+
ut("sdk_replay_snapshot_seconds", R / 1e3);
|
|
676
679
|
}
|
|
677
680
|
const S = p || !!v && f.type === B.Meta;
|
|
678
|
-
p = !1,
|
|
679
|
-
}, ...
|
|
681
|
+
p = !1, Ft(S, f), Ht({ uuid: q(), event: JSON.stringify(f), isValidStart: S, timestamp: Date.now() });
|
|
682
|
+
}, ...w }), g.isRecording = !!g.stopRecording, g.isRecording && (((f, v) => {
|
|
680
683
|
window.addEventListener("message", (S) => {
|
|
681
|
-
var
|
|
682
|
-
S.data.type ===
|
|
684
|
+
var R;
|
|
685
|
+
S.data.type === It && (ye.push({ source: S.source, origin: S.origin }), (R = S.source) == null || R.postMessage({ type: vt, settings: f, replayLibraryUrl: v }, { targetOrigin: S.origin }));
|
|
683
686
|
});
|
|
684
|
-
})(
|
|
687
|
+
})(w, u), H.on("survey.complete", (f) => {
|
|
685
688
|
var v;
|
|
686
|
-
v = { id: f, userAgent: window.navigator.userAgent },
|
|
687
|
-
}), E =
|
|
689
|
+
v = { id: f, userAgent: window.navigator.userAgent }, x("Sprig_SubmitSurvey", v);
|
|
690
|
+
}), E = x, k = Ut, K || (b = E, j = k, window.addEventListener("click", Oe, C), window.addEventListener("pointerdown", He, C), window.addEventListener("mousedown", Fe, C), window.addEventListener("keydown", Ne, C), window.addEventListener("scroll", Le, C), K = !0, Pt(), kt()));
|
|
688
691
|
}, "Error initializing replay");
|
|
689
|
-
}, isReplayRecording: () => g.isRecording,
|
|
690
|
-
|
|
692
|
+
}, isReplayPaused: W, isReplayRecording: () => g.isRecording, recordFullSnapshot: ue, recordReplayPaused: () => {
|
|
693
|
+
x("Sprig_ReplayPaused", { timestamp: Date.now() }), m.setItem("sprig.isReplayPaused", "true");
|
|
694
|
+
}, recordReplayResumed: () => {
|
|
695
|
+
m.removeItem("sprig.isReplayPaused"), x("Sprig_ReplayResumed", { timestamp: Date.now() });
|
|
696
|
+
}, scheduleCapture: ot, scheduleOrCaptureReplay: at, tryReplayAction: D, uploadReadyPendingCaptures: we }, Symbol.toStringTag, { value: "Module" }));
|
|
697
|
+
ct(zt);
|