@perspective-ai/sdk 1.1.0 → 1.1.3
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/browser.cjs +105 -6
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +13 -0
- package/dist/browser.d.ts +13 -0
- package/dist/browser.js +105 -6
- package/dist/browser.js.map +1 -1
- package/dist/cdn/perspective.global.js +17 -17
- package/dist/cdn/perspective.global.js.map +1 -1
- package/dist/constants.cjs +6 -3
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +4 -2
- package/dist/constants.d.ts +4 -2
- package/dist/constants.js +6 -3
- package/dist/constants.js.map +1 -1
- package/dist/index.cjs +81 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +60 -1
- package/dist/index.d.ts +60 -1
- package/dist/index.js +77 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/browser.test.ts +44 -1
- package/src/browser.ts +48 -3
- package/src/constants.ts +6 -2
- package/src/iframe.ts +8 -0
- package/src/index.ts +13 -0
- package/src/triggers.test.ts +272 -0
- package/src/triggers.ts +127 -0
- package/src/types.ts +19 -0
package/dist/browser.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/constants.ts
|
|
2
|
-
var SDK_VERSION = "1.1.
|
|
2
|
+
var SDK_VERSION = "1.1.3";
|
|
3
3
|
var FEATURES = {
|
|
4
4
|
RESIZE: 1 << 0,
|
|
5
5
|
// 0b0001
|
|
@@ -45,7 +45,9 @@ var DATA_ATTRS = {
|
|
|
45
45
|
brand: "data-perspective-brand",
|
|
46
46
|
brandDark: "data-perspective-brand-dark",
|
|
47
47
|
theme: "data-perspective-theme",
|
|
48
|
-
noStyle: "data-perspective-no-style"
|
|
48
|
+
noStyle: "data-perspective-no-style",
|
|
49
|
+
autoOpen: "data-perspective-auto-open",
|
|
50
|
+
showOnce: "data-perspective-show-once"
|
|
49
51
|
};
|
|
50
52
|
var MESSAGE_TYPES = {
|
|
51
53
|
// SDK -> Iframe (initialization)
|
|
@@ -79,9 +81,78 @@ var THEME_VALUES = {
|
|
|
79
81
|
system: "system"
|
|
80
82
|
};
|
|
81
83
|
var STORAGE_KEYS = {
|
|
82
|
-
anonId: "perspective-anon-id"
|
|
84
|
+
anonId: "perspective-anon-id",
|
|
85
|
+
triggerShown: "perspective-trigger-shown"
|
|
83
86
|
};
|
|
84
87
|
|
|
88
|
+
// src/triggers.ts
|
|
89
|
+
function parseTriggerAttr(value) {
|
|
90
|
+
const trimmed = value.trim();
|
|
91
|
+
if (trimmed.startsWith("timeout:")) {
|
|
92
|
+
const delay = parseInt(trimmed.slice("timeout:".length), 10);
|
|
93
|
+
if (isNaN(delay) || delay < 0) {
|
|
94
|
+
throw new Error(`Invalid timeout delay: "${value}"`);
|
|
95
|
+
}
|
|
96
|
+
return { type: "timeout", delay };
|
|
97
|
+
}
|
|
98
|
+
if (trimmed === "timeout") {
|
|
99
|
+
return { type: "timeout", delay: 5e3 };
|
|
100
|
+
}
|
|
101
|
+
if (trimmed === "exit-intent") {
|
|
102
|
+
return { type: "exit-intent" };
|
|
103
|
+
}
|
|
104
|
+
throw new Error(
|
|
105
|
+
`Unknown trigger type: "${value}". Expected "timeout:<ms>" or "exit-intent".`
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
function setupTrigger(config, callback) {
|
|
109
|
+
if (config.type === "timeout") {
|
|
110
|
+
const timer = setTimeout(callback, config.delay);
|
|
111
|
+
return () => clearTimeout(timer);
|
|
112
|
+
}
|
|
113
|
+
if (config.type === "exit-intent") {
|
|
114
|
+
const handler = (e) => {
|
|
115
|
+
if (e.clientY <= 0) {
|
|
116
|
+
callback();
|
|
117
|
+
document.removeEventListener("mouseleave", handler);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
document.addEventListener("mouseleave", handler);
|
|
121
|
+
return () => document.removeEventListener("mouseleave", handler);
|
|
122
|
+
}
|
|
123
|
+
const _exhaustive = config;
|
|
124
|
+
throw new Error(
|
|
125
|
+
`Unknown trigger type: ${_exhaustive.type}`
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
function storageKey(researchId) {
|
|
129
|
+
return `${STORAGE_KEYS.triggerShown}:${researchId}`;
|
|
130
|
+
}
|
|
131
|
+
function parseShowOnceAttr(value) {
|
|
132
|
+
if (!value) return "session";
|
|
133
|
+
const trimmed = value.trim();
|
|
134
|
+
if (trimmed === "visitor") return "visitor";
|
|
135
|
+
if (trimmed === "false") return false;
|
|
136
|
+
return "session";
|
|
137
|
+
}
|
|
138
|
+
function shouldShow(researchId, showOnce) {
|
|
139
|
+
if (showOnce === false) return true;
|
|
140
|
+
try {
|
|
141
|
+
const storage = showOnce === "visitor" ? localStorage : sessionStorage;
|
|
142
|
+
return storage.getItem(storageKey(researchId)) === null;
|
|
143
|
+
} catch {
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function markShown(researchId, showOnce) {
|
|
148
|
+
if (showOnce === false) return;
|
|
149
|
+
try {
|
|
150
|
+
const storage = showOnce === "visitor" ? localStorage : sessionStorage;
|
|
151
|
+
storage.setItem(storageKey(researchId), "1");
|
|
152
|
+
} catch {
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
85
156
|
// src/config.ts
|
|
86
157
|
var DEFAULT_HOST = "https://getperspective.ai";
|
|
87
158
|
var globalConfig = {};
|
|
@@ -181,6 +252,8 @@ function hexToRgba(hex, alpha) {
|
|
|
181
252
|
// src/iframe.ts
|
|
182
253
|
function isAllowedRedirectUrl(url) {
|
|
183
254
|
if (!url || typeof url !== "string") return false;
|
|
255
|
+
if (url.startsWith("/") && !url.startsWith("//") || url.startsWith("?") || url.startsWith("#"))
|
|
256
|
+
return true;
|
|
184
257
|
try {
|
|
185
258
|
const parsed = new URL(url, window.location.origin);
|
|
186
259
|
const protocol = parsed.protocol.toLowerCase();
|
|
@@ -1559,6 +1632,7 @@ function createFullpage(config) {
|
|
|
1559
1632
|
|
|
1560
1633
|
// src/browser.ts
|
|
1561
1634
|
var instances = /* @__PURE__ */ new Map();
|
|
1635
|
+
var triggerCleanups = /* @__PURE__ */ new Map();
|
|
1562
1636
|
var configCache = /* @__PURE__ */ new Map();
|
|
1563
1637
|
var styledButtons = /* @__PURE__ */ new Map();
|
|
1564
1638
|
var buttonThemeMediaQuery = null;
|
|
@@ -1738,8 +1812,13 @@ function destroy(researchId) {
|
|
|
1738
1812
|
function destroyAll() {
|
|
1739
1813
|
instances.forEach((instance) => instance.unmount());
|
|
1740
1814
|
instances.clear();
|
|
1815
|
+
triggerCleanups.forEach((cleanup) => cleanup());
|
|
1816
|
+
triggerCleanups.clear();
|
|
1741
1817
|
styledButtons.clear();
|
|
1742
1818
|
teardownButtonThemeListener();
|
|
1819
|
+
if (hasDom()) {
|
|
1820
|
+
document.querySelectorAll("[data-perspective-initialized]").forEach((el) => el.removeAttribute("data-perspective-initialized"));
|
|
1821
|
+
}
|
|
1743
1822
|
}
|
|
1744
1823
|
function autoInit() {
|
|
1745
1824
|
if (!hasDom()) return;
|
|
@@ -1764,9 +1843,29 @@ function autoInit() {
|
|
|
1764
1843
|
if (el.hasAttribute("data-perspective-initialized")) return;
|
|
1765
1844
|
el.setAttribute("data-perspective-initialized", "true");
|
|
1766
1845
|
const researchId = el.getAttribute(DATA_ATTRS.popup);
|
|
1767
|
-
if (researchId)
|
|
1768
|
-
|
|
1769
|
-
|
|
1846
|
+
if (!researchId) return;
|
|
1847
|
+
const params = parseParamsAttr(el);
|
|
1848
|
+
const brandConfig = extractBrandConfig(el);
|
|
1849
|
+
const autoOpenAttr = el.getAttribute(DATA_ATTRS.autoOpen);
|
|
1850
|
+
if (autoOpenAttr) {
|
|
1851
|
+
try {
|
|
1852
|
+
const trigger = parseTriggerAttr(autoOpenAttr);
|
|
1853
|
+
const showOnce = parseShowOnceAttr(
|
|
1854
|
+
el.getAttribute(DATA_ATTRS.showOnce)
|
|
1855
|
+
);
|
|
1856
|
+
if (shouldShow(researchId, showOnce)) {
|
|
1857
|
+
triggerCleanups.get(researchId)?.();
|
|
1858
|
+
const cleanup = setupTrigger(trigger, () => {
|
|
1859
|
+
triggerCleanups.delete(researchId);
|
|
1860
|
+
markShown(researchId, showOnce);
|
|
1861
|
+
init({ researchId, type: "popup", params, ...brandConfig });
|
|
1862
|
+
});
|
|
1863
|
+
triggerCleanups.set(researchId, cleanup);
|
|
1864
|
+
}
|
|
1865
|
+
} catch (e) {
|
|
1866
|
+
console.warn("[Perspective]", e.message);
|
|
1867
|
+
}
|
|
1868
|
+
} else {
|
|
1770
1869
|
styleButton(el, DEFAULT_THEME, brandConfig);
|
|
1771
1870
|
el.addEventListener("click", (e) => {
|
|
1772
1871
|
e.preventDefault();
|