@sprig-technologies/sprig-browser 2.34.0 → 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-DE6rbUl1.js → core-9nFfVPj6.js} +105 -103
- package/dist/{core-i4jnjCfb.cjs → core-B84vH8bq.cjs} +3 -3
- package/dist/core.cjs +1 -1
- package/dist/core.d.ts +52 -15
- package/dist/core.js +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +52 -15
- package/dist/index.js +2 -2
- package/dist/{metricsReporter-CEzz54S2.js → metricsReporter-BzXI6BiM.js} +25 -20
- package/dist/{metricsReporter-Cc-ZSIZD.cjs → metricsReporter-Dy3EDEs8.cjs} +1 -1
- package/dist/replay.cjs +1 -1
- package/dist/replay.js +281 -261
- package/dist/view-CDp4O3a5.js +2979 -0
- package/dist/view-DJLfkjCB.cjs +669 -0
- package/package.json +1 -1
- package/dist/view-Bze4Vd-1.cjs +0 -669
- package/dist/view-C3KUMRoa.js +0 -2752
package/dist/replay.js
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
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
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
16
|
function xe(e) {
|
|
17
|
-
|
|
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 M(e.apply(
|
|
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
30
|
const o = () => {
|
|
31
31
|
r(t.error || new DOMException("AbortError", "AbortError"));
|
|
@@ -34,8 +34,8 @@ function gt(e) {
|
|
|
34
34
|
a();
|
|
35
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
40
|
function M(e) {
|
|
41
41
|
if (e instanceof IDBRequest) return function(n) {
|
|
@@ -46,53 +46,53 @@ function M(e) {
|
|
|
46
46
|
o(n.error);
|
|
47
47
|
};
|
|
48
48
|
});
|
|
49
|
-
return
|
|
49
|
+
return K.set(a, n), a;
|
|
50
50
|
}(e);
|
|
51
51
|
if (Y.has(e)) return Y.get(e);
|
|
52
|
-
const t =
|
|
53
|
-
return t !== e && (Y.set(e, t),
|
|
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
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
64
|
if (ee.get(t)) return ee.get(t);
|
|
65
|
-
const n = t.replace(/FromIndex$/, ""), a = t !== n, r =
|
|
66
|
-
if (!(n in (a ? IDBIndex : IDBObjectStore).prototype) || !r && !
|
|
67
|
-
const o = async function(s, ...
|
|
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
68
|
const i = this.transaction(s, r ? "readwrite" : "readonly");
|
|
69
69
|
let u = i.store;
|
|
70
|
-
return a && (u = u.index(
|
|
70
|
+
return a && (u = u.index(c.shift())), (await Promise.all([u[n](...c), r && i.done]))[0];
|
|
71
71
|
};
|
|
72
72
|
return ee.set(t, o), o;
|
|
73
73
|
}
|
|
74
|
-
xe((e) => ({ ...e, get: (t, n, a) =>
|
|
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
|
-
xe((e) => ({ ...e, get: (t, n, a) =>
|
|
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,13 +115,13 @@ const It = "sprigReplayIframeLoaded", vt = "sprigReplayIframeSettings", St = "sp
|
|
|
115
115
|
setLimit(e) {
|
|
116
116
|
this.capacity = e;
|
|
117
117
|
}
|
|
118
|
-
}(2),
|
|
118
|
+
}(2), _e = async ({ apiUrl: e, surveyId: t, uploadId: n, etags: a, headers: r, responseGroupUuid: o, replayDuration: s, eventDigest: c }, i = !1) => {
|
|
119
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 u = await
|
|
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
123
|
return d.info("MarkUploadDone", { surveyId: t }), u;
|
|
124
|
-
},
|
|
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;
|
|
@@ -148,12 +148,12 @@ const It = "sprigReplayIframeLoaded", vt = "sprigReplayIframeSettings", St = "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 Re = (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
|
-
},
|
|
174
|
+
}, Ne = (e, t) => {
|
|
175
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
|
-
|
|
181
|
+
Ct.includes(e.key) && (t = { key: e.key }, b == null || b("Sprig_Keystroke", t));
|
|
182
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,88 +193,106 @@ const Re = (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
|
-
} },
|
|
204
|
+
} }, Ve = () => window.indexedDB && window.IDBKeyRange && window.CompressionStream, I = (() => {
|
|
205
205
|
const e = m.getItem("sprig.sessionId");
|
|
206
206
|
if (e) return d.info("SessionIDFound", { savedSessionId: e }), m.removeItem("sprig.sessionId"), e;
|
|
207
|
-
const t =
|
|
207
|
+
const t = X();
|
|
208
208
|
return d.info("GeneratedSessionID", { uuid: t }), t;
|
|
209
|
-
})(),
|
|
209
|
+
})(), ue = () => {
|
|
210
210
|
m.setItem("sprig.disableReplayRecording", "disabled");
|
|
211
|
-
},
|
|
211
|
+
}, T = () => !!m.getItem("sprig.disableReplayRecording"), z = () => !!m.getItem("sprig.isReplayPaused");
|
|
212
212
|
window.addEventListener("beforeunload", () => {
|
|
213
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
|
|
226
|
-
const o = await
|
|
225
|
+
var c, i, u, y;
|
|
226
|
+
const o = await l.openDB(), s = await o.get("events", r);
|
|
227
227
|
if (s != null && s.event) {
|
|
228
|
-
const p = JSON.parse(s.event), h = t > ((i = (
|
|
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
229
|
if (!h && !w) return null;
|
|
230
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
|
|
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
|
-
}, xt = ["did not allow mutations", "called in an invalid security context"],
|
|
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
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
288
|
return function(e, t, { blocked: n, upgrade: a, blocking: r, terminated: o } = {}) {
|
|
271
|
-
const s = indexedDB.open(e, t),
|
|
289
|
+
const s = indexedDB.open(e, t), c = M(s);
|
|
272
290
|
return a && (s.onupgradeneeded = (i) => {
|
|
273
291
|
a(M(s.result), i.oldVersion, i.newVersion, M(s.transaction), i);
|
|
274
|
-
}), n && (s.onblocked = (i) => n(i.oldVersion, i.newVersion, i)),
|
|
292
|
+
}), n && (s.onblocked = (i) => n(i.oldVersion, i.newVersion, i)), c.then((i) => {
|
|
275
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
297
|
if (n === 0 && m.setItem("sprig.pendingCount", "0"), !e.objectStoreNames.contains("events")) {
|
|
280
298
|
const a = e.createObjectStore("events", { keyPath: "uuid" });
|
|
@@ -292,29 +310,29 @@ const c = 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 =
|
|
326
|
+
const n = IDBKeyRange.only(t), a = await this.getTransaction(e), r = a.store.index("sessionId");
|
|
309
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 =
|
|
335
|
+
const a = IDBKeyRange.upperBound(t, !0), r = await this.getTransaction(e), o = r.store.index("timestamp");
|
|
318
336
|
for await (const s of o.iterate(a)) n(s.value) && await s.delete();
|
|
319
337
|
await r.done;
|
|
320
338
|
}
|
|
@@ -324,25 +342,27 @@ const c = 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)), o =
|
|
328
|
-
for await (const i of s.iterate(
|
|
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 });
|
|
329
347
|
await o.done;
|
|
330
348
|
}
|
|
331
349
|
async deleteChunkUploads(e, t) {
|
|
332
|
-
const n = IDBKeyRange.only([t, e]), a =
|
|
350
|
+
const n = IDBKeyRange.only([t, e]), a = await this.getTransaction("chunkUploads");
|
|
333
351
|
let o = await a.store.index("[uploadId+status]").openCursor(n);
|
|
334
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")
|
|
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]);
|
|
339
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 });
|
|
@@ -351,42 +371,42 @@ const c = new class {
|
|
|
351
371
|
}
|
|
352
372
|
async markPendingHeatmapsReady(e) {
|
|
353
373
|
if (parseInt(m.getItem("sprig.pendingCount") ?? "0") === 0) return null;
|
|
354
|
-
const t = Date.now(), n =
|
|
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
376
|
const o = r.value;
|
|
357
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
|
-
}(),
|
|
362
|
-
let
|
|
363
|
-
const O = () =>
|
|
364
|
-
|
|
365
|
-
},
|
|
381
|
+
}(), x = [];
|
|
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 () => {
|
|
366
386
|
if (!O()) return void window.clearInterval(Ke);
|
|
367
|
-
if (
|
|
368
|
-
const e =
|
|
369
|
-
Date.now() - e > 35e3 && (
|
|
370
|
-
},
|
|
371
|
-
if (
|
|
372
|
-
|
|
373
|
-
const e = await
|
|
387
|
+
if (ze(), !ve(x)) return;
|
|
388
|
+
const e = x[0].timestamp;
|
|
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
|
-
},
|
|
395
|
+
Ie.splice(0, e.length).forEach((t) => t(e.shift())), e.forEach((t) => A.push(t)), ne = !1;
|
|
396
|
+
}, Lt = () => {
|
|
377
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,49 +414,49 @@ const O = () => G && !L && Date.now() <= J, 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(), o = new CompressionStream("gzip"), s = o.writable.getWriter(),
|
|
401
|
-
return s.write(
|
|
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
|
-
},
|
|
437
|
+
return ze(), e;
|
|
438
|
+
}, Ze = (e) => {
|
|
419
439
|
var r, o, s;
|
|
420
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);
|
|
421
|
-
N++, e.push({ timestamp: t, type: B.Custom, data: { tag: "Sprig_Meta", payload: { ...
|
|
422
|
-
},
|
|
423
|
-
O() && !
|
|
424
|
-
const n =
|
|
425
|
-
if (!
|
|
426
|
-
d.info("Capturing always-on event array to upload"),
|
|
427
|
-
const a = await
|
|
428
|
-
a && await
|
|
429
|
-
})(),
|
|
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 () => {
|
|
444
|
+
const n = x.splice(0);
|
|
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);
|
|
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
|
-
|
|
435
|
-
const t = { disabled: L, metadata:
|
|
454
|
+
x.length && (e = x[0].timestamp);
|
|
455
|
+
const t = { disabled: L, metadata: j, uploadUrls: A, currentIndex: N, pendingEventTimestamp: e, expirationTimestamp: q };
|
|
436
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 {
|
|
@@ -447,7 +467,7 @@ const Ze = async (e, t) => {
|
|
|
447
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();
|
|
@@ -457,100 +477,100 @@ const Ze = async (e, t) => {
|
|
|
457
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
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;
|
|
465
485
|
if (!o) return;
|
|
466
486
|
g.scrollEventUuids[o] = e.uuid;
|
|
467
487
|
}
|
|
468
|
-
|
|
469
|
-
},
|
|
470
|
-
|
|
471
|
-
if (
|
|
472
|
-
const e =
|
|
473
|
-
|
|
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
525
|
}, $t = async (e, t, n, a, r) => {
|
|
506
|
-
const o = Math.min(e + r, n), s = await
|
|
526
|
+
const o = Math.min(e + r, n), s = await Ye(() => l.getEventsBetween(e, o), "sdk_replay_get_events_between_seconds");
|
|
507
527
|
if (!(s != null && s.length)) return d.debug("NoEventsFound"), { validStartFound: a, events: [] };
|
|
508
528
|
if (!a) {
|
|
509
529
|
d.debug("ValidStartSearch");
|
|
510
|
-
let
|
|
530
|
+
let c = -1;
|
|
511
531
|
return s == null || s.forEach((i, u) => {
|
|
512
532
|
if (!i.isValidStart) return;
|
|
513
533
|
const y = i.timestamp <= t;
|
|
514
|
-
(
|
|
515
|
-
}),
|
|
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) };
|
|
516
536
|
}
|
|
517
537
|
return { validStartFound: a, events: s };
|
|
518
|
-
},
|
|
519
|
-
const n = await (async (a) =>
|
|
538
|
+
}, nt = (e) => Promise.all(e.map(async (t) => {
|
|
539
|
+
const n = await (async (a) => Me.execute(async () => {
|
|
520
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
544
|
const o = (s = r.headers) == null ? void 0 : s.get("ETag");
|
|
525
545
|
if (!o) throw new Error(`Upload response did not include etag for upload ${a.uploadId}, part ${a.chunkIndex}`);
|
|
526
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((o, s) => (o.find((
|
|
552
|
+
const n = t.reduce((o, s) => (o.find((c) => c.chunkIndex === s.chunkIndex) || o.push(s), o), []);
|
|
533
553
|
n.sort((o, s) => o.chunkIndex - s.chunkIndex);
|
|
534
554
|
const a = n.map((o) => ({ ETag: o.etag, PartNumber: o.chunkIndex })).filter((o) => o.ETag !== null), r = n[0];
|
|
535
|
-
await
|
|
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);
|
|
536
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
568
|
const o = new TextEncoder();
|
|
549
569
|
let s = null;
|
|
550
|
-
const
|
|
570
|
+
const c = new CompressionStream("gzip"), i = c.writable.getWriter();
|
|
551
571
|
let u = !1, y = !1, [p, h] = [0, 0], w = [];
|
|
552
|
-
for (let
|
|
553
|
-
if ({ validStartFound: y, events: w } = await $t(
|
|
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
|
}
|
|
@@ -558,82 +578,82 @@ const we = async (e = !1) => {
|
|
|
558
578
|
const f = w.map((R) => R.event);
|
|
559
579
|
f.push(`{"timestamp":${r}}`);
|
|
560
580
|
const v = `${u ? "," : "["}${f}`, S = o.encode(v);
|
|
561
|
-
|
|
581
|
+
et(() => {
|
|
562
582
|
i.write(S);
|
|
563
583
|
}, "sdk_replay_compression_seconds"), u = !0;
|
|
564
584
|
}
|
|
565
|
-
if (h - p <
|
|
585
|
+
if (h - p < tt) return d.debug("ReplayTooShort"), null;
|
|
566
586
|
const E = o.encode("]");
|
|
567
|
-
return i.write(E), i.close(), s = new Uint8Array(await new Response(
|
|
587
|
+
return i.write(E), i.close(), s = new Uint8Array(await new Response(c.readable).arrayBuffer()), s;
|
|
568
588
|
})(n - e, n);
|
|
569
589
|
}, Pe = async (e) => {
|
|
570
|
-
const { surveyId: t, responseGroupId: n, visitorId: a, apiUrl: r, completeUploadHeaders: o, replayParams: s, triggerTimestamp:
|
|
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
592
|
const u = ((p, h, w) => {
|
|
573
|
-
const E = p.length,
|
|
593
|
+
const E = p.length, P = 1024 * h * 1024, f = Math.ceil(E / w), v = Math.max(P, f), S = [];
|
|
574
594
|
let R = 0;
|
|
575
595
|
for (; R < E; ) S.push(p.slice(R, R + v)), R += v;
|
|
576
596
|
return S;
|
|
577
597
|
})(i, s.minimumChunkSizeMb, s.signedUrls.length), y = await Promise.all(u.map(async (p, h) => {
|
|
578
|
-
const w =
|
|
579
|
-
return await (await
|
|
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
|
|
602
|
+
await nt(h), await Promise.all(p.map((w) => at(w)));
|
|
583
603
|
})([s.uploadId], y);
|
|
584
|
-
},
|
|
585
|
-
if (
|
|
586
|
-
const { isHeatmap: n, isStandalone: a, replayParams: r, triggerTimestamp: o, responseGroupId: s } = e,
|
|
587
|
-
setTimeout(() =>
|
|
588
|
-
r.replayDurationType === "before" ? await Pe(e) : await
|
|
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 Pe(e), n &&
|
|
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
616
|
const i = 35 + r.replayDurationSeconds, u = o - 1e3 * i, y = o;
|
|
597
|
-
await
|
|
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
632
|
const o = { ...e, replayParams: { ...e.replayParams } };
|
|
613
633
|
e.replayParams.replayDurationType === "beforeAndAfter" && (o.replayParams.replayDurationSeconds *= 2), o.replayParams.replayDurationType = "before";
|
|
614
634
|
const s = e.triggerTimestamp + 1e3 * e.replayParams.replayDurationSeconds;
|
|
615
|
-
o.triggerTimestamp = s,
|
|
616
|
-
},
|
|
617
|
-
|
|
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, o = await
|
|
644
|
+
const r = window.UserLeap._API_URL, o = await _e({ surveyId: e, responseGroupUuid: t, eventDigest: n, apiUrl: r, headers: a }, !0);
|
|
625
645
|
return !(o != null && o.error);
|
|
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 (o &&
|
|
631
|
-
|
|
632
|
-
} }),
|
|
633
|
-
if (a && m.setItem("sprig.teardownAfterCapture", "true"),
|
|
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
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;
|
|
@@ -641,21 +661,21 @@ const we = async (e = !1) => {
|
|
|
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 s = O() ? 30 : 0,
|
|
655
|
-
if (!
|
|
674
|
+
const s = O() ? 30 : 0, c = Math.max(e ?? 0, s);
|
|
675
|
+
if (!c) return d.debug("MissingDuration");
|
|
656
676
|
d.debug("ReplayInit"), await D(async () => {
|
|
657
677
|
var i;
|
|
658
|
-
n != null && n.minDuration && (
|
|
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();
|
|
659
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(
|
|
@@ -669,29 +689,29 @@ const we = async (e = !1) => {
|
|
|
669
689
|
if (!y) return d.error("RecordScriptFailed");
|
|
670
690
|
let p = !0, h = 0;
|
|
671
691
|
const w = { checkoutEveryNms: 3e4, sampling: { input: "last", scroll: 250, media: 800 }, ...n };
|
|
672
|
-
var E,
|
|
692
|
+
var E, P;
|
|
673
693
|
g.stopRecording = y({ emit: (f, v) => {
|
|
674
|
-
if (f.type === B.Custom && (
|
|
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
697
|
const R = performance.now() - h;
|
|
678
|
-
|
|
698
|
+
lt("sdk_replay_snapshot_seconds", R / 1e3);
|
|
679
699
|
}
|
|
680
700
|
const S = p || !!v && f.type === B.Meta;
|
|
681
|
-
p = !1,
|
|
701
|
+
p = !1, Ht(S, f), jt({ uuid: X(), event: JSON.stringify(f), isValidStart: S, timestamp: Date.now() });
|
|
682
702
|
}, ...w }), g.isRecording = !!g.stopRecording, g.isRecording && (((f, v) => {
|
|
683
703
|
window.addEventListener("message", (S) => {
|
|
684
704
|
var R;
|
|
685
|
-
S.data.type ===
|
|
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
|
-
})(w, u),
|
|
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
|
-
}, isReplayPaused:
|
|
693
|
-
|
|
712
|
+
}, isReplayPaused: z, isReplayRecording: () => g.isRecording, recordFullSnapshot: le, recordReplayPaused: () => {
|
|
713
|
+
U("Sprig_ReplayPaused", { timestamp: Date.now() }), m.setItem("sprig.isReplayPaused", "true");
|
|
694
714
|
}, recordReplayResumed: () => {
|
|
695
|
-
m.removeItem("sprig.isReplayPaused"),
|
|
696
|
-
}, scheduleCapture:
|
|
697
|
-
|
|
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);
|