@sightspool/sdk 0.2.1 → 0.3.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/dist/index.cjs +158 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +39 -12
- package/dist/index.js.map +1 -1
- package/dist/probe-BNGMQQ5C.js +113 -0
- package/dist/probe-BNGMQQ5C.js.map +1 -0
- package/dist/sdk.global.js +25 -4
- package/dist/sdk.global.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -199,6 +199,125 @@ input { font: inherit; font-size: 13px; width: 100%; box-sizing: border-box; pad
|
|
|
199
199
|
}
|
|
200
200
|
});
|
|
201
201
|
|
|
202
|
+
// src/probe.ts
|
|
203
|
+
var probe_exports = {};
|
|
204
|
+
__export(probe_exports, {
|
|
205
|
+
showProbe: () => showProbe
|
|
206
|
+
});
|
|
207
|
+
function findSlot(slot) {
|
|
208
|
+
try {
|
|
209
|
+
return document.querySelector(`[data-sightspool-slot="${slot}"]`);
|
|
210
|
+
} catch (e) {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function showProbe(config) {
|
|
215
|
+
return new Promise((resolve) => {
|
|
216
|
+
if (typeof document === "undefined") {
|
|
217
|
+
resolve({ dismissed: true, mounted: false });
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const anchor = config.slot ? findSlot(config.slot) : null;
|
|
221
|
+
if (config.slot && !anchor) {
|
|
222
|
+
resolve({ mounted: false });
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
let settled = false;
|
|
226
|
+
const inline = !!anchor;
|
|
227
|
+
const host = document.createElement(inline ? "span" : "div");
|
|
228
|
+
const shadow = host.attachShadow({ mode: "open" });
|
|
229
|
+
function teardown() {
|
|
230
|
+
try {
|
|
231
|
+
host.remove();
|
|
232
|
+
} catch (e) {
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
function finish(result, disclose) {
|
|
236
|
+
if (settled) return;
|
|
237
|
+
settled = true;
|
|
238
|
+
resolve(result);
|
|
239
|
+
if (disclose) {
|
|
240
|
+
disclosure();
|
|
241
|
+
setTimeout(teardown, DISCLOSURE_MS);
|
|
242
|
+
} else {
|
|
243
|
+
teardown();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const style = document.createElement("style");
|
|
247
|
+
style.textContent = inline ? INLINE_STYLE : FLOATING_STYLE;
|
|
248
|
+
shadow.appendChild(style);
|
|
249
|
+
const wrap = document.createElement(inline ? "span" : "div");
|
|
250
|
+
if (!inline) wrap.className = "wrap";
|
|
251
|
+
shadow.appendChild(wrap);
|
|
252
|
+
function container() {
|
|
253
|
+
wrap.innerHTML = "";
|
|
254
|
+
if (inline) return wrap;
|
|
255
|
+
const c = document.createElement("div");
|
|
256
|
+
c.className = "card";
|
|
257
|
+
wrap.appendChild(c);
|
|
258
|
+
return c;
|
|
259
|
+
}
|
|
260
|
+
function probe() {
|
|
261
|
+
const c = container();
|
|
262
|
+
if (!inline) {
|
|
263
|
+
const x = document.createElement("button");
|
|
264
|
+
x.className = "x";
|
|
265
|
+
x.textContent = "\xD7";
|
|
266
|
+
x.setAttribute("aria-label", "Dismiss");
|
|
267
|
+
x.onclick = () => finish({ dismissed: true, mounted: true }, false);
|
|
268
|
+
c.appendChild(x);
|
|
269
|
+
}
|
|
270
|
+
const b = document.createElement("button");
|
|
271
|
+
b.className = "probe";
|
|
272
|
+
b.textContent = config.label;
|
|
273
|
+
b.onclick = () => finish({ voted: true, mounted: true }, true);
|
|
274
|
+
c.appendChild(b);
|
|
275
|
+
}
|
|
276
|
+
function disclosure() {
|
|
277
|
+
const c = container();
|
|
278
|
+
const p = document.createElement("p");
|
|
279
|
+
p.className = "done";
|
|
280
|
+
p.textContent = config.disclosure;
|
|
281
|
+
c.appendChild(p);
|
|
282
|
+
}
|
|
283
|
+
try {
|
|
284
|
+
(anchor != null ? anchor : document.body).appendChild(host);
|
|
285
|
+
probe();
|
|
286
|
+
} catch (e) {
|
|
287
|
+
finish({ dismissed: true, mounted: false }, false);
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
var FLOATING_STYLE, INLINE_STYLE, DISCLOSURE_MS;
|
|
292
|
+
var init_probe = __esm({
|
|
293
|
+
"src/probe.ts"() {
|
|
294
|
+
FLOATING_STYLE = `
|
|
295
|
+
:host { all: initial; }
|
|
296
|
+
.wrap { position: fixed; bottom: 20px; right: 20px; z-index: 2147483000;
|
|
297
|
+
width: 340px; max-width: calc(100vw - 32px); font-family: system-ui, -apple-system, sans-serif; }
|
|
298
|
+
.card { position: relative; background: #fff; color: #18181b; border: 1px solid #e4e4e7;
|
|
299
|
+
border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,.12); padding: 16px; }
|
|
300
|
+
.probe { font: inherit; font-size: 13px; cursor: pointer; display: block; width: 100%;
|
|
301
|
+
text-align: left; border: 1px dashed #a1a1aa; border-radius: 8px; padding: 10px 12px;
|
|
302
|
+
background: #fafafa; color: #3f3f46; }
|
|
303
|
+
.probe:hover { border-color: #18181b; color: #18181b; }
|
|
304
|
+
.x { position: absolute; top: 8px; right: 10px; border: none; background: none; font-size: 16px;
|
|
305
|
+
color: #a1a1aa; padding: 2px 6px; cursor: pointer; }
|
|
306
|
+
.done { font-size: 13px; color: #18181b; margin: 0; line-height: 1.4; }
|
|
307
|
+
`;
|
|
308
|
+
INLINE_STYLE = `
|
|
309
|
+
:host { all: initial; display: inline-block; max-width: 100%; }
|
|
310
|
+
.probe { font: inherit; font-family: system-ui, -apple-system, sans-serif; font-size: 13px;
|
|
311
|
+
cursor: pointer; display: inline-block; text-align: left; border: 1px dashed #a1a1aa;
|
|
312
|
+
border-radius: 8px; padding: 8px 12px; background: transparent; color: #52525b; }
|
|
313
|
+
.probe:hover { border-color: #18181b; color: #18181b; }
|
|
314
|
+
.done { font-family: system-ui, -apple-system, sans-serif; font-size: 13px; color: #52525b;
|
|
315
|
+
margin: 0; line-height: 1.4; border: 1px dashed #d4d4d8; border-radius: 8px; padding: 8px 12px; }
|
|
316
|
+
`;
|
|
317
|
+
DISCLOSURE_MS = 3200;
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
|
|
202
321
|
// src/survey.ts
|
|
203
322
|
var survey_exports = {};
|
|
204
323
|
__export(survey_exports, {
|
|
@@ -725,7 +844,7 @@ function canPrompt(state, now, caps = DEFAULT_CAPS) {
|
|
|
725
844
|
}
|
|
726
845
|
|
|
727
846
|
// src/intervention.ts
|
|
728
|
-
var RENDERABLE = /* @__PURE__ */ new Set(["survey"]);
|
|
847
|
+
var RENDERABLE = /* @__PURE__ */ new Set(["survey", "demand_probe"]);
|
|
729
848
|
function str(v, max) {
|
|
730
849
|
if (typeof v !== "string") return void 0;
|
|
731
850
|
const t = v.trim();
|
|
@@ -748,6 +867,14 @@ function normalizeServed(raw) {
|
|
|
748
867
|
const type = str(r.type, 40);
|
|
749
868
|
if (!id || !type || !RENDERABLE.has(type)) return null;
|
|
750
869
|
const cfg = r.config && typeof r.config === "object" ? r.config : {};
|
|
870
|
+
if (type === "demand_probe") {
|
|
871
|
+
const label = str(cfg.label, 200);
|
|
872
|
+
const disclosure = str(cfg.disclosure, 300);
|
|
873
|
+
if (!label || !disclosure) return null;
|
|
874
|
+
const rawSlot = str(cfg.slot, 64);
|
|
875
|
+
const slot = rawSlot && /^[a-z0-9][a-z0-9_-]*$/i.test(rawSlot) ? rawSlot : void 0;
|
|
876
|
+
return { id, type, config: { label, disclosure, ...slot ? { slot } : {} } };
|
|
877
|
+
}
|
|
751
878
|
const question = str(cfg.question, 500);
|
|
752
879
|
if (!question) return null;
|
|
753
880
|
const options = Array.isArray(cfg.options) ? cfg.options.map((o) => str(o, 200)).filter((o) => !!o).slice(0, 6) : void 0;
|
|
@@ -756,7 +883,7 @@ function normalizeServed(raw) {
|
|
|
756
883
|
...options && options.length ? { options } : {},
|
|
757
884
|
allow_text: cfg.allow_text === true
|
|
758
885
|
};
|
|
759
|
-
return { id, type, config };
|
|
886
|
+
return { id, type: "survey", config };
|
|
760
887
|
}
|
|
761
888
|
function pickRespondentKey(userId, persisted, sessionRef) {
|
|
762
889
|
const uid = str(userId, 200);
|
|
@@ -929,20 +1056,39 @@ async function maybeServeIntervention(c) {
|
|
|
929
1056
|
debug: c.config.debug
|
|
930
1057
|
});
|
|
931
1058
|
if (!served || !c.running) return;
|
|
1059
|
+
const prevShown = c.interventionsShown;
|
|
1060
|
+
const prevPromptAt = c.fatigue.lastPromptAt;
|
|
932
1061
|
c.surveyOnScreen = true;
|
|
933
1062
|
c.interventionsShown += 1;
|
|
934
1063
|
c.fatigue.lastPromptAt = Date.now();
|
|
935
1064
|
try {
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
1065
|
+
if (served.type === "demand_probe") {
|
|
1066
|
+
const { showProbe: showProbe2 } = await Promise.resolve().then(() => (init_probe(), probe_exports));
|
|
1067
|
+
const result = await showProbe2(served.config);
|
|
1068
|
+
if (!result.mounted) {
|
|
1069
|
+
c.interventionsShown = prevShown;
|
|
1070
|
+
c.fatigue.lastPromptAt = prevPromptAt;
|
|
1071
|
+
} else if (result.voted) {
|
|
1072
|
+
submitResponse({
|
|
1073
|
+
endpoint: c.config.endpoint,
|
|
1074
|
+
key: c.config.key,
|
|
1075
|
+
interventionId: served.id,
|
|
1076
|
+
response: { choice: "vote" },
|
|
1077
|
+
respondentKey
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
1080
|
+
} else {
|
|
1081
|
+
const { showSurvey: showSurvey2 } = await Promise.resolve().then(() => (init_survey(), survey_exports));
|
|
1082
|
+
const result = await showSurvey2(served.config);
|
|
1083
|
+
if (!result.dismissed && (result.choice || result.text)) {
|
|
1084
|
+
submitResponse({
|
|
1085
|
+
endpoint: c.config.endpoint,
|
|
1086
|
+
key: c.config.key,
|
|
1087
|
+
interventionId: served.id,
|
|
1088
|
+
response: { choice: result.choice, text: result.text },
|
|
1089
|
+
respondentKey
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
946
1092
|
}
|
|
947
1093
|
} catch (e) {
|
|
948
1094
|
} finally {
|