@superfeedback/widget 0.0.18 → 0.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,126 +1,148 @@
1
+ import { t as tryCatchAsync } from "./dist-CU9w03k6.js";
1
2
  var VISITOR_ID_KEY = "sf_visitor_id", SessionTracker = class {
2
- appId;
3
- apiUrl;
4
- visitorId;
5
- sessionId;
6
- segmentStart;
7
- accumulatedMs = 0;
8
- isVisible = !0;
9
- constructor(e, a) {
10
- this.appId = e, this.apiUrl = a, this.segmentStart = Date.now(), this.visitorId = this.getOrCreateVisitorId(), this.sessionId = crypto.randomUUID(), this.setupListeners();
11
- }
12
- getOrCreateVisitorId() {
3
+ #e;
4
+ #t;
5
+ #n;
6
+ #r;
7
+ #i;
8
+ #a = 0;
9
+ #o = !0;
10
+ constructor(e, r) {
11
+ this.#e = e, this.#t = r, this.#i = Date.now(), this.#n = this.#s(), this.#r = crypto.randomUUID(), this.#m();
12
+ }
13
+ #s() {
13
14
  try {
14
- let a = localStorage.getItem(VISITOR_ID_KEY);
15
- if (a) return a;
16
- let o = crypto.randomUUID();
17
- return localStorage.setItem(VISITOR_ID_KEY, o), o;
15
+ let e = localStorage.getItem(VISITOR_ID_KEY);
16
+ if (e) return e;
17
+ let i = crypto.randomUUID();
18
+ return localStorage.setItem(VISITOR_ID_KEY, i), i;
18
19
  } catch {
19
20
  return crypto.randomUUID();
20
21
  }
21
22
  }
22
- getOS() {
23
+ #c() {
23
24
  let e = navigator.userAgent;
24
25
  return e.includes("Windows") ? "Windows" : e.includes("Mac OS") ? "macOS" : e.includes("Linux") ? "Linux" : e.includes("Android") ? "Android" : e.includes("iOS") || e.includes("iPhone") || e.includes("iPad") ? "iOS" : "Unknown";
25
26
  }
26
- getDeviceType() {
27
+ #l() {
27
28
  let e = navigator.userAgent;
28
29
  return /Tablet|iPad/i.test(e) ? "tablet" : /Mobile|iPhone|Android.*Mobile/i.test(e) ? "mobile" : "desktop";
29
30
  }
30
- getTotalDurationMs() {
31
- let e = this.isVisible ? Date.now() - this.segmentStart : 0;
32
- return this.accumulatedMs + e;
31
+ #u() {
32
+ let e = this.#o ? Date.now() - this.#i : 0;
33
+ return this.#a + e;
33
34
  }
34
- getSessionData() {
35
+ #d() {
35
36
  return {
36
- appId: this.appId,
37
- visitorId: this.visitorId,
38
- sessionId: this.sessionId,
39
- sessionDurationMs: this.getTotalDurationMs(),
37
+ appId: this.#e,
38
+ visitorId: this.#n,
39
+ sessionId: this.#r,
40
+ sessionDurationMs: this.#u(),
40
41
  userAgent: navigator.userAgent,
41
- os: this.getOS(),
42
- deviceType: this.getDeviceType()
42
+ os: this.#c(),
43
+ deviceType: this.#l()
43
44
  };
44
45
  }
45
- sendSession() {
46
- if (this.getTotalDurationMs() < 1e3) return;
47
- let e = this.getSessionData(), a = `${this.apiUrl}/api/external/v1/apps/${this.appId}/sessions`, o = JSON.stringify(e);
48
- fetch(a, {
46
+ #f() {
47
+ if (this.#u() < 1e3) return;
48
+ let e = this.#d(), r = `${this.#t}/api/external/v1/apps/${this.#e}/sessions`, i = JSON.stringify(e);
49
+ fetch(r, {
49
50
  method: "POST",
50
51
  headers: { "Content-Type": "application/json" },
51
- body: o,
52
+ body: i,
52
53
  keepalive: !0,
53
54
  credentials: "omit"
54
- }).catch(() => {}), this.accumulatedMs = 0, this.segmentStart = Date.now();
55
+ }).catch(() => {}), this.#a = 0, this.#i = Date.now();
55
56
  }
56
- onVisibilityChange() {
57
- document.visibilityState === "hidden" ? (this.accumulatedMs += Date.now() - this.segmentStart, this.isVisible = !1, this.sendSession()) : (this.isVisible = !0, this.segmentStart = Date.now());
57
+ #p() {
58
+ document.visibilityState === "hidden" ? (this.#a += Date.now() - this.#i, this.#o = !1, this.#f()) : (this.#o = !0, this.#i = Date.now());
58
59
  }
59
- setupListeners() {
60
+ #m() {
60
61
  window.addEventListener("beforeunload", () => {
61
- this.sendSession();
62
+ this.#f();
62
63
  }), document.addEventListener("visibilitychange", () => {
63
- this.onVisibilityChange();
64
+ this.#p();
64
65
  }), window.addEventListener("pagehide", () => {
65
- this.sendSession();
66
+ this.#f();
66
67
  });
67
68
  }
68
69
  destroy() {
69
- this.sendSession();
70
+ this.#f();
70
71
  }
71
72
  }, __widgetBaseUrl = null;
72
73
  typeof document < "u" && document.currentScript && (__widgetBaseUrl = document.currentScript.src);
73
74
  function loadScript(e) {
74
- return new Promise((a, o) => {
75
- let s = document.createElement("script");
76
- s.src = e, s.onload = () => a(), s.onerror = () => o(/* @__PURE__ */ Error(`Failed to load: ${e}`)), document.head.appendChild(s);
75
+ return new Promise((r, i) => {
76
+ let a = document.createElement("script");
77
+ a.src = e, a.onload = () => r(), a.onerror = () => i(/* @__PURE__ */ Error(`Failed to load: ${e}`)), document.head.appendChild(a);
77
78
  });
78
79
  }
79
- async function loadWidgetModule() {
80
+ var iifeLoader = async () => {
81
+ if (window.__superfeedback_widget) return window.__superfeedback_widget;
82
+ if (!__widgetBaseUrl) throw Error("Cannot determine widget chunk URL");
83
+ await loadScript(`${__widgetBaseUrl}/dist/widget.iife.js`);
84
+ let e = window.__superfeedback_widget;
85
+ if (!e) throw Error("Widget chunk failed to register");
86
+ return e;
87
+ }, loadWidgetModule = async () => {
80
88
  try {
81
89
  return await import("./widget.js");
82
90
  } catch {
83
- if (!__widgetBaseUrl) throw Error("Cannot determine widget chunk URL");
84
- await loadScript(`${__widgetBaseUrl}/dist/widget.iife.js`);
85
- let e = window.__superfeedback_widget;
86
- if (!e) throw Error("Widget chunk failed to register");
87
- return e;
88
- }
89
- }
90
- var Superfeedback = class e {
91
- static instance = null;
92
- static CONTAINER_ID = "superfeedback-widget";
93
- app = null;
94
- container = null;
95
- sessionTracker = null;
96
- isLoading = !1;
97
- constructor(o) {
98
- this.container = document.createElement("div"), this.container.id = e.CONTAINER_ID, this.container.style.position = "fixed", this.container.style.bottom = "20px", this.container.style.right = "20px", this.container.style.zIndex = "9999", document.body.appendChild(this.container), o.appId && (this.sessionTracker = new SessionTracker(o.appId, "https://app.superfeedback.ai")), !o.appId && !o.apiKey && console.error("Superfeedback: appId or apiKey is required"), o.apiKey && this.loadWidget(o);
99
- }
100
- async loadWidget(e) {
101
- if (!this.isLoading) {
102
- this.isLoading = !0;
103
- try {
104
- let { createApp: a, Root: o } = await loadWidgetModule(), s = a(o, {
105
- apiKey: e.apiKey,
106
- readonly: e.readonly,
107
- defaultOpen: e.defaultOpen,
108
- config: e.config,
109
- strategy: e.strategy
110
- });
111
- this.app = s, s.mount(this.container);
112
- } catch (e) {
113
- console.error("Superfeedback: Failed to load widget", e);
114
- } finally {
115
- this.isLoading = !1;
91
+ return iifeLoader();
92
+ }
93
+ }, Superfeedback = class r {
94
+ static #e = null;
95
+ static #t = "superfeedback-widget";
96
+ #n = null;
97
+ #r = null;
98
+ #i = null;
99
+ #a = !1;
100
+ constructor(e) {
101
+ if (this.#r = document.createElement("div"), this.#r.id = r.#t, this.#r.style.position = "fixed", this.#r.style.bottom = "20px", this.#r.style.right = "20px", this.#r.style.zIndex = "9999", document.body.appendChild(this.#r), e.appId && (this.#i = new SessionTracker(e.appId, "https://app.superfeedback.ai")), !e.appId && !e.projectId) {
102
+ console.error("Superfeedback: appId or projectId is required");
103
+ return;
104
+ }
105
+ this.#o(e);
106
+ }
107
+ async #o(r) {
108
+ if (this.#a) return;
109
+ this.#a = !0;
110
+ let i = r.projectId;
111
+ if (!i && r.appId) {
112
+ let [a, o] = await tryCatchAsync(this.#s(r.appId));
113
+ if (o) {
114
+ console.error("Superfeedback: Failed to resolve projectId from appId", o), this.#a = !1;
115
+ return;
116
116
  }
117
+ i = a;
118
+ }
119
+ if (!i) {
120
+ console.error("Superfeedback: Could not determine projectId"), this.#a = !1;
121
+ return;
117
122
  }
123
+ let [a, o] = await tryCatchAsync(loadWidgetModule());
124
+ if (o || !this.#r) {
125
+ o && console.error("Superfeedback: Failed to load widget", o), this.#r || console.error("Superfeedback: Container element not found"), this.#a = !1;
126
+ return;
127
+ }
128
+ let { createApp: s, Root: c } = a, l = s(c, {
129
+ projectId: i,
130
+ previewMode: r.previewMode,
131
+ config: r.config,
132
+ strategy: r.strategy
133
+ });
134
+ this.#n = l, l.mount(this.#r), this.#a = !1;
135
+ }
136
+ async #s(e) {
137
+ let r = await fetch(`https://app.superfeedback.ai/external/v1/apps/${e}/config`);
138
+ if (!r.ok) throw Error(`Failed to resolve appId: ${r.statusText}`);
139
+ return (await r.json()).projectId;
118
140
  }
119
- static init(a) {
120
- return e.instance ||= new e(typeof a == "string" ? { apiKey: a } : a), e.instance;
141
+ static init(e) {
142
+ return r.#e ||= new r(e), r.#e;
121
143
  }
122
144
  destroy() {
123
- this.sessionTracker &&= (this.sessionTracker.destroy(), null), this.app &&= (this.app.unmount(), null), this.container &&= (this.container.remove(), null), e.instance = null;
145
+ this.#i &&= (this.#i.destroy(), null), this.#n &&= (this.#n.unmount(), null), this.#r &&= (this.#r.remove(), null), r.#e = null;
124
146
  }
125
147
  };
126
148
  function getAppIdFromScript() {