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