@tekibo/feedpulse-sdk 0.7.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -83
- package/dist/core/cookies.d.ts +37 -0
- package/dist/core/struggle-detector.d.ts +33 -0
- package/dist/core/tracker.d.ts +38 -0
- package/dist/core/types.d.ts +59 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +127 -176
- package/dist/nuxt/BotPanel.vue.d.ts +17 -0
- package/dist/nuxt/FeedPulseBot.vue.d.ts +24 -0
- package/dist/nuxt/FeedPulseProvider.vue.d.ts +21 -0
- package/dist/nuxt/FeedPulseWidget.vue.d.ts +10 -0
- package/dist/nuxt/composables.d.ts +4 -0
- package/dist/nuxt/consent-banner.vue.d.ts +16 -0
- package/dist/nuxt/index.d.ts +5 -0
- package/dist/nuxt.d.ts +2 -0
- package/dist/nuxt.js +2 -2
- package/dist/nuxt.mjs +283 -336
- package/dist/react/FeedPulseBot.d.ts +21 -0
- package/dist/react/FeedPulseProvider.d.ts +13 -0
- package/dist/react/FeedPulseWidget.d.ts +8 -0
- package/dist/react/consent-banner.d.ts +11 -0
- package/dist/react/hooks.d.ts +1 -0
- package/dist/react/index.d.ts +4 -0
- package/dist/react.d.ts +2 -0
- package/dist/react.js +3 -3
- package/dist/react.mjs +275 -315
- package/dist/struggle-detector-CT3YShuG.js +1 -0
- package/dist/{struggle-detector-BqTHgw95.mjs → struggle-detector-Cwe3PD9s.mjs} +40 -25
- package/package.json +4 -11
- package/templates/nextjs-proxy.ts +36 -36
- package/templates/nuxt-bot-proxy.ts +60 -93
- package/templates/nuxt-proxy.ts +44 -44
- package/bin/feedpulse-bot-build.mjs +0 -121
- package/dist/server.js +0 -1
- package/dist/server.mjs +0 -18
- package/dist/struggle-detector-DV52qDLp.js +0 -1
- package/templates/nuxt-config-id-route.ts +0 -15
package/dist/index.mjs
CHANGED
|
@@ -1,104 +1,105 @@
|
|
|
1
|
-
function
|
|
1
|
+
function h(r) {
|
|
2
2
|
for (var e = 1; e < arguments.length; e++) {
|
|
3
3
|
var i = arguments[e];
|
|
4
|
-
for (var
|
|
5
|
-
|
|
4
|
+
for (var t in i)
|
|
5
|
+
t !== "__proto__" && (r[t] = i[t]);
|
|
6
6
|
}
|
|
7
|
-
return
|
|
7
|
+
return r;
|
|
8
8
|
}
|
|
9
|
-
var
|
|
10
|
-
read: function(
|
|
11
|
-
return
|
|
9
|
+
var g = {
|
|
10
|
+
read: function(r) {
|
|
11
|
+
return r[0] === '"' && (r = r.slice(1, -1)), r.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent);
|
|
12
12
|
},
|
|
13
|
-
write: function(
|
|
14
|
-
return encodeURIComponent(
|
|
13
|
+
write: function(r) {
|
|
14
|
+
return encodeURIComponent(r).replace(
|
|
15
15
|
/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,
|
|
16
16
|
decodeURIComponent
|
|
17
17
|
);
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
|
-
function
|
|
21
|
-
function i(
|
|
20
|
+
function f(r, e) {
|
|
21
|
+
function i(n, a, s) {
|
|
22
22
|
if (!(typeof document > "u")) {
|
|
23
|
-
|
|
24
|
-
var
|
|
25
|
-
for (var
|
|
26
|
-
|
|
27
|
-
return document.cookie =
|
|
23
|
+
s = h({}, e, s), typeof s.expires == "number" && (s.expires = new Date(Date.now() + s.expires * 864e5)), s.expires && (s.expires = s.expires.toUTCString()), n = encodeURIComponent(n).replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent).replace(/[()]/g, escape);
|
|
24
|
+
var l = "";
|
|
25
|
+
for (var u in s)
|
|
26
|
+
s[u] && (l += "; " + u, s[u] !== !0 && (l += "=" + s[u].split(";")[0]));
|
|
27
|
+
return document.cookie = n + "=" + r.write(a, n) + l;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
function
|
|
31
|
-
if (!(typeof document > "u" || arguments.length && !
|
|
32
|
-
for (var
|
|
33
|
-
var
|
|
30
|
+
function t(n) {
|
|
31
|
+
if (!(typeof document > "u" || arguments.length && !n)) {
|
|
32
|
+
for (var a = document.cookie ? document.cookie.split("; ") : [], s = {}, l = 0; l < a.length; l++) {
|
|
33
|
+
var u = a[l].split("="), m = u.slice(1).join("=");
|
|
34
34
|
try {
|
|
35
|
-
var
|
|
36
|
-
if (
|
|
35
|
+
var d = decodeURIComponent(u[0]);
|
|
36
|
+
if (d in s || (s[d] = r.read(m, d)), n === d)
|
|
37
37
|
break;
|
|
38
38
|
} catch {
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
return
|
|
41
|
+
return n ? s[n] : s;
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
return Object.create(
|
|
45
45
|
{
|
|
46
46
|
set: i,
|
|
47
|
-
get:
|
|
48
|
-
remove: function(
|
|
47
|
+
get: t,
|
|
48
|
+
remove: function(n, a) {
|
|
49
49
|
i(
|
|
50
|
-
|
|
50
|
+
n,
|
|
51
51
|
"",
|
|
52
|
-
|
|
52
|
+
h({}, a, {
|
|
53
53
|
expires: -1
|
|
54
54
|
})
|
|
55
55
|
);
|
|
56
56
|
},
|
|
57
|
-
withAttributes: function(
|
|
58
|
-
return
|
|
57
|
+
withAttributes: function(n) {
|
|
58
|
+
return f(this.converter, h({}, this.attributes, n));
|
|
59
59
|
},
|
|
60
|
-
withConverter: function(
|
|
61
|
-
return
|
|
60
|
+
withConverter: function(n) {
|
|
61
|
+
return f(h({}, this.converter, n), this.attributes);
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
65
|
attributes: { value: Object.freeze(e) },
|
|
66
|
-
converter: { value: Object.freeze(
|
|
66
|
+
converter: { value: Object.freeze(r) }
|
|
67
67
|
}
|
|
68
68
|
);
|
|
69
69
|
}
|
|
70
|
-
var c =
|
|
71
|
-
const
|
|
70
|
+
var c = f(g, { path: "/" });
|
|
71
|
+
const o = {
|
|
72
72
|
USER_ID: "__fp_uid",
|
|
73
73
|
SESSION_ID: "__fp_sid",
|
|
74
74
|
SESSION_START: "__fp_ss",
|
|
75
75
|
CONSENT: "__fp_consent",
|
|
76
76
|
UTM: "__fp_utm"
|
|
77
|
-
},
|
|
78
|
-
function
|
|
77
|
+
}, p = 1 / 48, S = 365, I = 365, k = 30;
|
|
78
|
+
function w() {
|
|
79
79
|
return typeof window < "u";
|
|
80
80
|
}
|
|
81
|
-
function v(
|
|
82
|
-
if (!
|
|
81
|
+
function v(r) {
|
|
82
|
+
if (!r)
|
|
83
83
|
return null;
|
|
84
84
|
try {
|
|
85
|
-
return JSON.parse(
|
|
85
|
+
return JSON.parse(r);
|
|
86
86
|
} catch {
|
|
87
87
|
return null;
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
-
class
|
|
90
|
+
class D {
|
|
91
|
+
transientSession = null;
|
|
91
92
|
initSession() {
|
|
92
|
-
const e = !!c.get(
|
|
93
|
-
let i = c.get(
|
|
94
|
-
return i || (i = crypto.randomUUID(),
|
|
93
|
+
const e = !!c.get(o.USER_ID);
|
|
94
|
+
let i = c.get(o.SESSION_ID) ?? null, t = Number(c.get(o.SESSION_START) || Date.now());
|
|
95
|
+
return i || (i = crypto.randomUUID(), t = Date.now()), c.set(o.SESSION_ID, i, { expires: p }), c.set(o.SESSION_START, String(t), { expires: p }), { sessionId: i, sessionStart: t, isReturningUser: e };
|
|
95
96
|
}
|
|
96
97
|
initUser() {
|
|
97
|
-
let e = c.get(
|
|
98
|
-
return e || (e = crypto.randomUUID(), c.set(
|
|
98
|
+
let e = c.get(o.USER_ID) ?? null;
|
|
99
|
+
return e || (e = crypto.randomUUID(), c.set(o.USER_ID, e, { expires: I })), e;
|
|
99
100
|
}
|
|
100
101
|
getConsent() {
|
|
101
|
-
return v(c.get(
|
|
102
|
+
return v(c.get(o.CONSENT));
|
|
102
103
|
}
|
|
103
104
|
setConsent(e) {
|
|
104
105
|
const i = {
|
|
@@ -108,10 +109,12 @@ class S {
|
|
|
108
109
|
version: e.version,
|
|
109
110
|
timestamp: Date.now()
|
|
110
111
|
};
|
|
111
|
-
return c.set(
|
|
112
|
+
return c.set(o.CONSENT, JSON.stringify(i), { expires: S }), i;
|
|
112
113
|
}
|
|
113
114
|
clearAnalyticsCookies() {
|
|
114
|
-
|
|
115
|
+
for (const e of [o.USER_ID, o.SESSION_ID, o.SESSION_START, o.UTM])
|
|
116
|
+
c.remove(e);
|
|
117
|
+
this.transientSession = null;
|
|
115
118
|
}
|
|
116
119
|
isConsentExpired() {
|
|
117
120
|
const e = this.getConsent();
|
|
@@ -121,107 +124,56 @@ class S {
|
|
|
121
124
|
return Date.now() - e.timestamp > i;
|
|
122
125
|
}
|
|
123
126
|
captureUTM() {
|
|
124
|
-
if (!
|
|
127
|
+
if (!w())
|
|
125
128
|
return null;
|
|
126
129
|
const e = new URLSearchParams(window.location.search), i = {};
|
|
127
|
-
for (const
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
+
for (const t of ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"]) {
|
|
131
|
+
const n = e.get(t);
|
|
132
|
+
n && (i[t] = n);
|
|
130
133
|
}
|
|
131
|
-
return Object.keys(i).length === 0 ? v(c.get(
|
|
134
|
+
return Object.keys(i).length === 0 ? v(c.get(o.UTM)) : (c.set(o.UTM, JSON.stringify(i), { expires: k }), i);
|
|
132
135
|
}
|
|
133
136
|
getAllData(e) {
|
|
134
|
-
|
|
137
|
+
if (!e)
|
|
138
|
+
return this.transientSession === null && (this.transientSession = { sessionId: crypto.randomUUID(), sessionStart: Date.now() }), {
|
|
139
|
+
userId: null,
|
|
140
|
+
...this.transientSession,
|
|
141
|
+
consent: this.getConsent(),
|
|
142
|
+
utm: null,
|
|
143
|
+
isReturningUser: !1
|
|
144
|
+
};
|
|
145
|
+
const { sessionId: i, sessionStart: t, isReturningUser: n } = this.initSession();
|
|
135
146
|
return {
|
|
136
147
|
userId: e ? this.initUser() : null,
|
|
137
148
|
sessionId: i,
|
|
138
|
-
sessionStart:
|
|
149
|
+
sessionStart: t,
|
|
139
150
|
consent: this.getConsent(),
|
|
140
151
|
utm: this.captureUTM(),
|
|
141
|
-
isReturningUser: e ?
|
|
152
|
+
isReturningUser: e ? n : !1
|
|
142
153
|
};
|
|
143
154
|
}
|
|
144
155
|
}
|
|
145
|
-
class D {
|
|
146
|
-
constructor() {
|
|
147
|
-
this.cursorEl = null;
|
|
148
|
-
}
|
|
149
|
-
createCursor() {
|
|
150
|
-
if (this.cursorEl)
|
|
151
|
-
return this.cursorEl;
|
|
152
|
-
const e = document.createElement("div");
|
|
153
|
-
return e.id = "__fp_bot_cursor", e.innerHTML = '<svg width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M5 3l14 9-7 1-4 7L5 3z" fill="#6366f1" stroke="white" stroke-width="1.5"/></svg>', Object.assign(e.style, {
|
|
154
|
-
position: "fixed",
|
|
155
|
-
zIndex: "999999",
|
|
156
|
-
pointerEvents: "none",
|
|
157
|
-
transition: "left 0.6s ease, top 0.6s ease",
|
|
158
|
-
transform: "translate(-4px,-4px)",
|
|
159
|
-
left: "50%",
|
|
160
|
-
top: "50%",
|
|
161
|
-
opacity: "0"
|
|
162
|
-
}), document.body.appendChild(e), this.cursorEl = e, e;
|
|
163
|
-
}
|
|
164
|
-
async moveTo(e, i) {
|
|
165
|
-
const s = this.createCursor();
|
|
166
|
-
s.style.left = `${e}px`, s.style.top = `${i}px`, await new Promise((t) => setTimeout(t, 700));
|
|
167
|
-
}
|
|
168
|
-
async clickAnimation(e, i) {
|
|
169
|
-
if (!document.getElementById("__fp_cursor_styles")) {
|
|
170
|
-
const t = document.createElement("style");
|
|
171
|
-
t.id = "__fp_cursor_styles", t.textContent = "@keyframes fp-ripple{from{transform:scale(0);opacity:1}to{transform:scale(2);opacity:0}}", document.head.appendChild(t);
|
|
172
|
-
}
|
|
173
|
-
const s = document.createElement("div");
|
|
174
|
-
Object.assign(s.style, {
|
|
175
|
-
position: "fixed",
|
|
176
|
-
left: `${e - 16}px`,
|
|
177
|
-
top: `${i - 16}px`,
|
|
178
|
-
width: "32px",
|
|
179
|
-
height: "32px",
|
|
180
|
-
borderRadius: "50%",
|
|
181
|
-
background: "rgba(99,102,241,0.4)",
|
|
182
|
-
zIndex: "999998",
|
|
183
|
-
pointerEvents: "none",
|
|
184
|
-
animation: "fp-ripple 0.4s ease-out forwards"
|
|
185
|
-
}), document.body.appendChild(s), await new Promise((t) => setTimeout(t, 400)), s.remove();
|
|
186
|
-
}
|
|
187
|
-
async typeText(e, i) {
|
|
188
|
-
e.focus(), (e instanceof HTMLInputElement || e instanceof HTMLTextAreaElement) && (e.value = "");
|
|
189
|
-
for (const s of i)
|
|
190
|
-
await new Promise((t) => setTimeout(t, 60 + Math.random() * 40)), (e instanceof HTMLInputElement || e instanceof HTMLTextAreaElement) && (e.value += s, e.dispatchEvent(new Event("input", { bubbles: !0 })));
|
|
191
|
-
}
|
|
192
|
-
async perform(e) {
|
|
193
|
-
try {
|
|
194
|
-
const i = this.createCursor();
|
|
195
|
-
if (i.style.opacity = "1", e.type === "navigate" && e.value)
|
|
196
|
-
return await this.moveTo(window.innerWidth / 2, window.innerHeight / 2), await new Promise((d) => setTimeout(d, 300)), this.destroy(), window.location.href = e.value, { success: !0, message: `Navigating to ${e.value}...` };
|
|
197
|
-
if (!e.selector)
|
|
198
|
-
return { success: !1, message: "No target element specified." };
|
|
199
|
-
const t = !/[#.\[\]\s>:+~]/.test(e.selector) ? `[data-fp-id="${e.selector}"], #${e.selector}, [name="${e.selector}"]` : e.selector, n = document.querySelector(t);
|
|
200
|
-
if (!n)
|
|
201
|
-
return { success: !1, message: `Could not find "${e.label}" on the page.` };
|
|
202
|
-
const r = n.getBoundingClientRect(), a = r.left + r.width / 2, l = r.top + r.height / 2;
|
|
203
|
-
if (await this.moveTo(a, l), e.type === "click" && (await this.clickAnimation(a, l), n.click(), n.dispatchEvent(new MouseEvent("click", { bubbles: !0, cancelable: !0 }))), e.type === "scroll") {
|
|
204
|
-
n.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
205
|
-
const d = n.style.outline, h = n.style.outlineOffset;
|
|
206
|
-
n.style.outline = "2px solid #6366f1", n.style.outlineOffset = "3px", await new Promise((f) => setTimeout(f, 1500)), n.style.outline = d, n.style.outlineOffset = h;
|
|
207
|
-
}
|
|
208
|
-
if (e.type === "fill" && e.value && await this.typeText(n, e.value), e.type === "highlight") {
|
|
209
|
-
n.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
210
|
-
const d = n.style.outline, h = n.style.outlineOffset;
|
|
211
|
-
n.style.outline = "2px solid #6366f1", n.style.outlineOffset = "3px", await new Promise((f) => setTimeout(f, 1500)), n.style.outline = d, n.style.outlineOffset = h;
|
|
212
|
-
}
|
|
213
|
-
return await new Promise((d) => setTimeout(d, 400)), this.destroy(), { success: !0, message: `Done! I ${e.type}ed "${e.label}".` };
|
|
214
|
-
} catch {
|
|
215
|
-
return this.destroy(), { success: !1, message: "Something went wrong performing that action." };
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
destroy() {
|
|
219
|
-
this.cursorEl?.remove(), this.cursorEl = null;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
156
|
class _ {
|
|
157
|
+
config;
|
|
158
|
+
queue = [];
|
|
159
|
+
flushInterval = null;
|
|
160
|
+
sessionId = "";
|
|
161
|
+
observer = null;
|
|
162
|
+
intersectionObserver = null;
|
|
163
|
+
scrollFallbackListener = null;
|
|
164
|
+
resizeFallbackListener = null;
|
|
165
|
+
seenInView = /* @__PURE__ */ new Set();
|
|
166
|
+
cookieManager = new D();
|
|
167
|
+
cookieData = null;
|
|
168
|
+
analyticsConsented = !1;
|
|
169
|
+
isInitialized = !1;
|
|
170
|
+
beforeUnloadListener = null;
|
|
171
|
+
visibilityListener = null;
|
|
172
|
+
clickListener = null;
|
|
173
|
+
hoverStartListener = null;
|
|
174
|
+
hoverEndListener = null;
|
|
223
175
|
constructor(e) {
|
|
224
|
-
this.
|
|
176
|
+
this.config = {
|
|
225
177
|
proxyEndpoint: e.proxyEndpoint ?? "/api/fp-proxy",
|
|
226
178
|
batchInterval: e.batchInterval ?? 5e3,
|
|
227
179
|
debug: e.debug ?? !1
|
|
@@ -231,54 +183,54 @@ class _ {
|
|
|
231
183
|
!this.isBrowser() || this.isInitialized || (this.isInitialized = !0, this.refreshCookieData(), this.startFlushInterval(), this.attachGlobalListeners(), this.observeDOM());
|
|
232
184
|
}
|
|
233
185
|
attachGlobalListeners() {
|
|
234
|
-
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
x:
|
|
238
|
-
y:
|
|
186
|
+
this.clickListener = (t) => {
|
|
187
|
+
const n = t.target instanceof Element ? t.target.closest("[data-fp-id]") : null;
|
|
188
|
+
n && this.track("click", n.getAttribute("data-fp-id"), {
|
|
189
|
+
x: t.clientX,
|
|
190
|
+
y: t.clientY
|
|
239
191
|
});
|
|
240
|
-
}, { passive: !0 });
|
|
192
|
+
}, document.addEventListener("click", this.clickListener, { passive: !0 });
|
|
241
193
|
let e = 0, i = null;
|
|
242
|
-
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
}, { passive: !0 }),
|
|
246
|
-
if (!
|
|
194
|
+
this.hoverStartListener = (t) => {
|
|
195
|
+
const n = t.target instanceof Element ? t.target.closest("[data-fp-id]") : null;
|
|
196
|
+
n && (e = Date.now(), i = n.getAttribute("data-fp-id"));
|
|
197
|
+
}, document.addEventListener("mouseover", this.hoverStartListener, { passive: !0 }), this.hoverEndListener = (t) => {
|
|
198
|
+
if (!(t.target instanceof Element ? t.target.closest("[data-fp-id]") : null) || !i)
|
|
247
199
|
return;
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
}, { passive: !0 });
|
|
200
|
+
const a = Date.now() - e;
|
|
201
|
+
a > 500 && this.track("hover", i, { hoverDuration: a }), i = null;
|
|
202
|
+
}, document.addEventListener("mouseout", this.hoverEndListener, { passive: !0 });
|
|
251
203
|
}
|
|
252
204
|
observeDOM() {
|
|
253
|
-
const e = (
|
|
254
|
-
this.seenInView.has(
|
|
205
|
+
const e = (n) => {
|
|
206
|
+
this.seenInView.has(n) || (this.seenInView.add(n), this.track("scroll_into_view", n, {
|
|
255
207
|
scrollDepth: Math.round(window.scrollY / Math.max(1, document.body.scrollHeight) * 100)
|
|
256
208
|
}));
|
|
257
209
|
};
|
|
258
|
-
this.intersectionObserver = new IntersectionObserver((
|
|
259
|
-
for (const
|
|
260
|
-
const
|
|
261
|
-
!
|
|
210
|
+
this.intersectionObserver = new IntersectionObserver((n) => {
|
|
211
|
+
for (const a of n) {
|
|
212
|
+
const s = a.target.dataset.fpId;
|
|
213
|
+
!s || !a.isIntersecting || e(s);
|
|
262
214
|
}
|
|
263
215
|
}, { threshold: 0.1 });
|
|
264
216
|
const i = () => {
|
|
265
|
-
document.querySelectorAll("[data-fp-id]").forEach((
|
|
266
|
-
this.intersectionObserver?.observe(
|
|
217
|
+
document.querySelectorAll("[data-fp-id]").forEach((n) => {
|
|
218
|
+
this.intersectionObserver?.observe(n);
|
|
267
219
|
});
|
|
268
|
-
},
|
|
269
|
-
const
|
|
270
|
-
document.querySelectorAll("[data-fp-id]").forEach((
|
|
271
|
-
const
|
|
272
|
-
if (!
|
|
220
|
+
}, t = () => {
|
|
221
|
+
const n = window.innerHeight * 0.1, a = window.innerHeight * 0.9;
|
|
222
|
+
document.querySelectorAll("[data-fp-id]").forEach((s) => {
|
|
223
|
+
const l = s.dataset.fpId;
|
|
224
|
+
if (!l || this.seenInView.has(l))
|
|
273
225
|
return;
|
|
274
|
-
const
|
|
275
|
-
|
|
226
|
+
const u = s.getBoundingClientRect();
|
|
227
|
+
u.bottom >= n && u.top <= a && e(l);
|
|
276
228
|
});
|
|
277
229
|
};
|
|
278
|
-
i(),
|
|
230
|
+
i(), t(), this.scrollFallbackListener = () => t(), this.resizeFallbackListener = () => t(), window.addEventListener("scroll", this.scrollFallbackListener, { passive: !0 }), window.addEventListener("resize", this.resizeFallbackListener, { passive: !0 }), this.observer = new MutationObserver(() => i()), this.observer.observe(document.body, { childList: !0, subtree: !0 });
|
|
279
231
|
}
|
|
280
|
-
track(e, i,
|
|
281
|
-
this.isBrowser()
|
|
232
|
+
track(e, i, t) {
|
|
233
|
+
!this.isBrowser() || !this.analyticsConsented || (this.refreshCookieData(), this.queue.push({
|
|
282
234
|
elementId: i,
|
|
283
235
|
eventType: e,
|
|
284
236
|
sessionId: this.cookieData?.sessionId ?? this.sessionId,
|
|
@@ -296,12 +248,12 @@ class _ {
|
|
|
296
248
|
device: this.getDeviceType(),
|
|
297
249
|
browser: this.getBrowser(),
|
|
298
250
|
os: this.getOS(),
|
|
299
|
-
metadata:
|
|
251
|
+
metadata: t,
|
|
300
252
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
301
253
|
}));
|
|
302
254
|
}
|
|
303
|
-
trackFeedback(e, i,
|
|
304
|
-
this.isBrowser() && (!i && !
|
|
255
|
+
trackFeedback(e, i, t) {
|
|
256
|
+
this.isBrowser() && (!i && !t || (this.refreshCookieData(), this.sendImmediate([{
|
|
305
257
|
elementId: e ?? "__page__",
|
|
306
258
|
eventType: "feedback",
|
|
307
259
|
sessionId: this.cookieData?.sessionId ?? this.sessionId,
|
|
@@ -316,7 +268,7 @@ class _ {
|
|
|
316
268
|
consentAnalytics: this.cookieData?.consent?.analytics ?? !1,
|
|
317
269
|
page: window.location.pathname,
|
|
318
270
|
device: this.getDeviceType(),
|
|
319
|
-
metadata: { rating: i, message:
|
|
271
|
+
metadata: { rating: i, message: t },
|
|
320
272
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
321
273
|
}])));
|
|
322
274
|
}
|
|
@@ -335,8 +287,8 @@ class _ {
|
|
|
335
287
|
keepalive: !0
|
|
336
288
|
});
|
|
337
289
|
if (this.config.debug && i.ok) {
|
|
338
|
-
const
|
|
339
|
-
|
|
290
|
+
const t = await i.json().catch(() => null);
|
|
291
|
+
t?.ingested !== void 0 && t?.pipeline && globalThis.console.debug(`[FeedPulse] ${t.ingested} events via ${t.pipeline} pipeline`);
|
|
340
292
|
}
|
|
341
293
|
} catch {
|
|
342
294
|
}
|
|
@@ -369,12 +321,11 @@ class _ {
|
|
|
369
321
|
return e.includes("Windows") ? "Windows" : e.includes("Mac") ? "macOS" : e.includes("Linux") ? "Linux" : e.includes("Android") ? "Android" : /iPhone|iOS/.test(e) ? "iOS" : "Other";
|
|
370
322
|
}
|
|
371
323
|
destroy() {
|
|
372
|
-
this.flushInterval && clearInterval(this.flushInterval), this.beforeUnloadListener && window.removeEventListener("beforeunload", this.beforeUnloadListener), this.visibilityListener && document.removeEventListener("visibilitychange", this.visibilityListener), this.scrollFallbackListener && window.removeEventListener("scroll", this.scrollFallbackListener), this.resizeFallbackListener && window.removeEventListener("resize", this.resizeFallbackListener), this.observer?.disconnect(), this.intersectionObserver?.disconnect(), this.isInitialized = !1, this.flush();
|
|
324
|
+
this.flushInterval && clearInterval(this.flushInterval), this.beforeUnloadListener && window.removeEventListener("beforeunload", this.beforeUnloadListener), this.visibilityListener && document.removeEventListener("visibilitychange", this.visibilityListener), this.scrollFallbackListener && window.removeEventListener("scroll", this.scrollFallbackListener), this.resizeFallbackListener && window.removeEventListener("resize", this.resizeFallbackListener), this.clickListener && document.removeEventListener("click", this.clickListener), this.hoverStartListener && document.removeEventListener("mouseover", this.hoverStartListener), this.hoverEndListener && document.removeEventListener("mouseout", this.hoverEndListener), this.observer?.disconnect(), this.intersectionObserver?.disconnect(), this.isInitialized = !1, this.flush();
|
|
373
325
|
}
|
|
374
326
|
}
|
|
375
327
|
export {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
D as CursorActor,
|
|
328
|
+
o as COOKIE_KEYS,
|
|
329
|
+
D as CookieManager,
|
|
379
330
|
_ as FeedPulseTracker
|
|
380
331
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BotConfig } from '../core/types';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
botSessionId: string;
|
|
4
|
+
config: BotConfig;
|
|
5
|
+
unavailable?: boolean;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
8
|
+
close: () => any;
|
|
9
|
+
helpful: (value: boolean) => any;
|
|
10
|
+
escalated: () => any;
|
|
11
|
+
}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
12
|
+
onClose?: (() => any) | undefined;
|
|
13
|
+
onHelpful?: ((value: boolean) => any) | undefined;
|
|
14
|
+
onEscalated?: (() => any) | undefined;
|
|
15
|
+
}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
16
|
+
declare const _default: typeof __VLS_export;
|
|
17
|
+
export default _default;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BotConfig, BotFaqItem, BotFeature, BotFormField, BotNavigableElement } from '../core/types';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
faq?: BotFaqItem[];
|
|
4
|
+
pageContext?: string;
|
|
5
|
+
systemPrompt?: string;
|
|
6
|
+
canNavigate?: boolean;
|
|
7
|
+
navigableElements?: BotNavigableElement[];
|
|
8
|
+
canHelpForms?: boolean;
|
|
9
|
+
formGuide?: BotFormField[];
|
|
10
|
+
features?: BotFeature[];
|
|
11
|
+
escalateTo?: {
|
|
12
|
+
label: string;
|
|
13
|
+
url: string;
|
|
14
|
+
};
|
|
15
|
+
initialMessage?: string;
|
|
16
|
+
position?: "bottom-right" | "bottom-left";
|
|
17
|
+
config?: BotConfig;
|
|
18
|
+
};
|
|
19
|
+
declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
20
|
+
initialMessage: string;
|
|
21
|
+
position: "bottom-right" | "bottom-left";
|
|
22
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
23
|
+
declare const _default: typeof __VLS_export;
|
|
24
|
+
export default _default;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
proxyEndpoint?: string;
|
|
3
|
+
debug?: boolean;
|
|
4
|
+
consentRequired?: boolean;
|
|
5
|
+
};
|
|
6
|
+
declare var __VLS_1: {};
|
|
7
|
+
type __VLS_Slots = {} & {
|
|
8
|
+
default?: (props: typeof __VLS_1) => any;
|
|
9
|
+
};
|
|
10
|
+
declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
11
|
+
proxyEndpoint: string;
|
|
12
|
+
consentRequired: boolean;
|
|
13
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
14
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
15
|
+
declare const _default: typeof __VLS_export;
|
|
16
|
+
export default _default;
|
|
17
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
18
|
+
new (): {
|
|
19
|
+
$slots: S;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
id?: string;
|
|
3
|
+
placeholder?: string;
|
|
4
|
+
position?: "bottom-right" | "bottom-left" | "inline";
|
|
5
|
+
};
|
|
6
|
+
declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
7
|
+
position: "bottom-right" | "bottom-left" | "inline";
|
|
8
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
9
|
+
declare const _default: typeof __VLS_export;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type ConsentAction = "accept_all" | "reject_all" | "custom" | "withdraw";
|
|
2
|
+
declare const __VLS_export: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
3
|
+
consent: (state: {
|
|
4
|
+
analytics: boolean;
|
|
5
|
+
marketing: boolean;
|
|
6
|
+
action: ConsentAction;
|
|
7
|
+
}) => any;
|
|
8
|
+
}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{
|
|
9
|
+
onConsent?: ((state: {
|
|
10
|
+
analytics: boolean;
|
|
11
|
+
marketing: boolean;
|
|
12
|
+
action: ConsentAction;
|
|
13
|
+
}) => any) | undefined;
|
|
14
|
+
}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
|
|
15
|
+
declare const _default: typeof __VLS_export;
|
|
16
|
+
export default _default;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { useFeedPulse } from './composables';
|
|
2
|
+
export { default as FeedPulseBot } from './FeedPulseBot.vue';
|
|
3
|
+
export { default as ConsentBanner } from './consent-banner.vue';
|
|
4
|
+
export { default as FeedPulseProvider } from './FeedPulseProvider.vue';
|
|
5
|
+
export { default as FeedPulseWidget } from './FeedPulseWidget.vue';
|
package/dist/nuxt.d.ts
ADDED