@journeeze/sdk 0.1.0-rc.2 → 0.1.0-rc.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/AGENTS.md +16 -3
- package/CHANGELOG.md +12 -1
- package/README.md +298 -119
- package/dist/anchor-cPvFFTOS.js +1 -0
- package/dist/attach-DpioALxW.js +21 -0
- package/dist/chat-BgmB0rnW.js +64 -0
- package/dist/consent-DckCUvYR.js +1 -0
- package/dist/contract.js +1 -1
- package/dist/feedback-CtH1a_kQ.js +1 -0
- package/dist/help-w0O5Qu-4.js +105 -0
- package/dist/hook-DGWypoEO.js +1 -0
- package/dist/index-B_nob8S0.js +1 -2091
- package/dist/{index-CfCbJJXa.js → index-CwG2LrhO.js} +3 -3
- package/dist/index.js +3 -3
- package/dist/jobs-CAXbM5-g.js +45 -0
- package/dist/loader-BZiIDD1D.js +96 -0
- package/dist/mask-audit-Du3NPoG_.js +5 -0
- package/dist/react.js +12 -11
- package/dist/resolve-BfWByuTp.js +1 -97
- package/dist/script.js +10 -9
- package/dist/signals-amjMQyOy.js +1 -0
- package/dist/telemetry-CyRJDaVs.js +1 -0
- package/dist/transport-B64CfIcF.js +1 -0
- package/dist/types/chat/capture/attach.d.ts +41 -0
- package/dist/types/chat/capture/draw.d.ts +10 -0
- package/dist/types/chat/capture/geometry.d.ts +30 -0
- package/dist/types/chat/capture/styles.d.ts +1 -0
- package/dist/types/chat/shell/chat.d.ts +27 -0
- package/dist/types/chat/shell/converse.d.ts +95 -0
- package/dist/types/chat/shell/copy.d.ts +8 -0
- package/dist/types/chat/shell/model.d.ts +36 -0
- package/dist/types/chat/shell/session.d.ts +148 -0
- package/dist/types/chat/shell/styles.d.ts +1 -0
- package/dist/types/chat/shell/view.d.ts +18 -0
- package/dist/types/chat/transport.d.ts +5 -0
- package/dist/types/config.d.ts +17 -0
- package/dist/types/help/core/controller.d.ts +12 -3
- package/dist/types/help/core/events.d.ts +24 -0
- package/dist/types/help/core/help.d.ts +1 -0
- package/dist/types/help/core/panel.d.ts +16 -0
- package/dist/types/help/core/routing.d.ts +21 -0
- package/dist/types/help/ui/jobs/jobs.d.ts +24 -0
- package/dist/types/help/ui/jobs/model.d.ts +33 -0
- package/dist/types/help/ui/jobs/styles.d.ts +1 -0
- package/dist/types/loader.d.ts +2 -0
- package/dist/types/mask-detector.d.ts +22 -0
- package/dist/types/preview/flag.d.ts +2 -0
- package/dist/types/preview/mask-audit.d.ts +29 -0
- package/dist/types/schemas/feedback.d.ts +76 -0
- package/dist/types/schemas/finding.d.ts +22 -0
- package/dist/types/schemas/index.d.ts +6 -0
- package/dist/types/schemas/turn.d.ts +26 -0
- package/dist/types/signals/signals.d.ts +7 -3
- package/dist/types/signals/steps.d.ts +33 -0
- package/dist/types/telemetry/telemetry.d.ts +10 -0
- package/dist/types/types.d.ts +72 -1
- package/dist/types/widget/capture.d.ts +12 -1
- package/dist/types/widget/upload.d.ts +14 -0
- package/dist/types/widget.d.ts +1 -21
- package/dist/upload-Fu2qvSJV.js +14 -0
- package/dist/widget-B6mR1J3P.js +118 -0
- package/package.json +4 -2
- package/dist/consent-CoKD33Rm.js +0 -170
- package/dist/feedback-C4CYtS2A.js +0 -196
- package/dist/help-C1x-y2f9.js +0 -878
- package/dist/hook-BdG4UL4k.js +0 -91
- package/dist/loader-Ba4X-WNl.js +0 -95
- package/dist/signals-E3VEdmWH.js +0 -477
- package/dist/telemetry-Cik-cYzw.js +0 -140
- package/dist/transport-B5YJFQEF.js +0 -60
- package/dist/types/signals/signals.conformance.d.ts +0 -2
- package/dist/widget-DQZm8sAC.js +0 -1599
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
var $=Object.defineProperty;var N=(d,t,e)=>t in d?$(d,t,{enumerable:true,configurable:true,writable:true,value:e}):d[t]=e;var n=(d,t,e)=>N(d,typeof t!="symbol"?t+"":t,e);import{e as B,s as W,d as K,h as _,f as O,C as M,D as H,g as q,i as Y,j as G}from"./consent-DckCUvYR.js";import{i as R}from"./index-CwG2LrhO.js";import{c as J,s as V,p as X}from"./upload-Fu2qvSJV.js";import{m as jt,u as zt}from"./upload-Fu2qvSJV.js";import{s as Z,R as Q}from"./hook-DGWypoEO.js";import{d as tt,i as I,e as et,a as ot}from"./anchor-cPvFFTOS.js";import{feedbackChannel as it,widgetConfig as st}from"./feedback-CtH1a_kQ.js";const S="jz:preview",w="mask-audit";function nt(){try{const d=new URL(location.href),t=d.searchParams.get("jz_preview");return t===null?sessionStorage.getItem(S)===w:(d.searchParams.delete("jz_preview"),history.replaceState(history.state,"",d.href),t===w?sessionStorage.setItem(S,w):sessionStorage.removeItem(S),t===w)}catch{return false}}const U='<path d="M9 9h.01"/><path d="M15 9h.01"/>',rt={like:`<circle cx="12" cy="12" r="10"/><path d="M8 14s1.5 2 4 2 4-2 4-2"/>${U}`,dislike:`<circle cx="12" cy="12" r="10"/><path d="M16 16s-1.5-2-4-2-4 2-4 2"/>${U}`,understood:'<circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/>',confused:'<circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><path d="M12 17h.01"/>',close:'<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',persona:'<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',step:'<path d="M5 12h14"/><path d="m12 5 7 7-7 7"/>',info:'<circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/>'};function m(d,t=20){const e=document.createElement("template");return e.innerHTML=`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">${rt[d]}</svg>`,e.content.firstElementChild}const at=`
|
|
2
|
+
:host { all: initial; }
|
|
3
|
+
.jz {
|
|
4
|
+
--jz-canvas:#F7F7F5; --jz-surface:#FFFFFF; --jz-raised:#F0F0EC; --jz-ink:#1D2024; --jz-muted:#5D636B;
|
|
5
|
+
--jz-faint:#8A9099; --jz-rule:rgb(29 32 36 / 12%); --jz-accent:#3D63C9; --jz-accent-ink:#FFFFFF;
|
|
6
|
+
--jz-accent-soft:rgb(61 99 201 / 10%); --jz-polished:#2F7D4F; --jz-broken:#B42318; --jz-confused:#6E4FC2;
|
|
7
|
+
--jz-shadow:0 1px 3px rgb(0 0 0 / 12%);
|
|
8
|
+
font: 400 13px/1.45 Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
9
|
+
color: var(--jz-ink); -webkit-font-smoothing: antialiased;
|
|
10
|
+
}
|
|
11
|
+
@media (prefers-color-scheme: dark) {
|
|
12
|
+
.jz { --jz-canvas:#111316; --jz-surface:#181B1F; --jz-raised:#20242A; --jz-ink:#E8EAED; --jz-muted:#A3A9B2;
|
|
13
|
+
--jz-faint:#6F7680; --jz-rule:rgb(232 234 237 / 12%); --jz-accent:#7F9CF0; --jz-accent-ink:#111316;
|
|
14
|
+
--jz-accent-soft:rgb(127 156 240 / 14%); --jz-confused:#A48BEA; --jz-polished:#5DBB84; }
|
|
15
|
+
}
|
|
16
|
+
.jz *, .jz *::before, .jz *::after { box-sizing: border-box; }
|
|
17
|
+
/* Zero specificity: a component's own colour (.toggle, .primary, ...) must always win. */
|
|
18
|
+
:where(.jz button) { font: inherit; color: inherit; cursor: pointer; }
|
|
19
|
+
.jz :focus-visible { outline: 2px solid var(--jz-accent); outline-offset: 2px; }
|
|
20
|
+
.mono { font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
21
|
+
.sr { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
|
|
22
|
+
|
|
23
|
+
.toggle { position:fixed; right:32px; bottom:32px; z-index:2147483646; height:44px; padding:0 16px; display:flex; align-items:center;
|
|
24
|
+
gap:8px; border:0; border-radius:999px; background:#1D2024; color:#FFFFFF; box-shadow:var(--jz-shadow); font-weight:500; }
|
|
25
|
+
.toggle .dot { width:8px; height:8px; border-radius:50%; background:var(--jz-polished); }
|
|
26
|
+
.toggle .exit { color:#8A9099; }
|
|
27
|
+
.toggle:hover .exit { color:#FFFFFF; }
|
|
28
|
+
|
|
29
|
+
.layer { position:fixed; inset:0; z-index:2147483640; pointer-events:none; }
|
|
30
|
+
.hl { position:fixed; display:none; outline:1px solid var(--jz-accent); outline-offset:-1px; border-radius:2px; }
|
|
31
|
+
.hl.masked { outline:1px dashed var(--jz-faint);
|
|
32
|
+
background:repeating-linear-gradient(45deg, rgb(138 144 153 / 10%) 0 4px, rgb(138 144 153 / 20%) 4px 8px); }
|
|
33
|
+
.tag { position:absolute; left:0; top:-18px; padding:1px 6px; border-radius:2px; background:var(--jz-accent); color:#FFFFFF;
|
|
34
|
+
font-size:10px; line-height:16px; white-space:nowrap; max-width:280px; overflow:hidden; text-overflow:ellipsis; }
|
|
35
|
+
.hl.masked .tag { background:var(--jz-muted); text-transform:uppercase; letter-spacing:.06em; }
|
|
36
|
+
.pin { position:fixed; width:24px; height:24px; margin:-12px 0 0 -12px; border-radius:50%; display:flex; align-items:center;
|
|
37
|
+
justify-content:center; background:var(--jz-accent); color:#FFFFFF; font-size:12px; font-weight:500; box-shadow:var(--jz-shadow); }
|
|
38
|
+
|
|
39
|
+
.pop, .sheet, .checkin, .toast { position:fixed; z-index:2147483645; background:var(--jz-surface); color:var(--jz-ink);
|
|
40
|
+
border:1px solid var(--jz-rule); box-shadow:var(--jz-shadow); }
|
|
41
|
+
.pop { width:400px; max-width:calc(100vw - 32px); max-height:calc(100vh - 32px); overflow:auto; padding:24px; border-radius:10px;
|
|
42
|
+
animation: jz-in 180ms ease-out; }
|
|
43
|
+
@keyframes jz-in { from { opacity:0; transform:translateY(4px); } to { opacity:1; transform:none; } }
|
|
44
|
+
.pop-head { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:20px; }
|
|
45
|
+
.pop h2 { margin:0; font-size:14px; font-weight:500; }
|
|
46
|
+
.close { width:32px; height:32px; display:flex; align-items:center; justify-content:center; border:0; border-radius:6px;
|
|
47
|
+
background:transparent; color:var(--jz-faint); }
|
|
48
|
+
.close:hover { color:var(--jz-ink); }
|
|
49
|
+
.chips { display:flex; flex-wrap:wrap; gap:8px; margin-bottom:20px; }
|
|
50
|
+
.chip { display:inline-flex; align-items:center; gap:4px; padding:2px 8px; border-radius:999px; background:var(--jz-raised);
|
|
51
|
+
color:var(--jz-muted); font-size:11px; }
|
|
52
|
+
.reactions { display:flex; border:1px solid var(--jz-rule); border-radius:8px; overflow:hidden; margin-bottom:20px; }
|
|
53
|
+
.reaction { flex:1; min-height:56px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px;
|
|
54
|
+
padding:12px 4px; border:0; border-right:1px solid var(--jz-rule); background:transparent; color:var(--jz-muted); }
|
|
55
|
+
.reaction:last-child { border-right:0; }
|
|
56
|
+
.reaction:hover { background:var(--jz-canvas); }
|
|
57
|
+
.reaction span { font-size:10px; font-weight:500; }
|
|
58
|
+
.reaction[data-r="confused"] { color:var(--jz-confused); }
|
|
59
|
+
.reaction[aria-checked="true"] { background:var(--jz-accent-soft); color:var(--jz-accent); }
|
|
60
|
+
.reaction[data-r="confused"][aria-checked="true"] { background:rgb(110 79 194 / 10%); color:var(--jz-confused); }
|
|
61
|
+
.comment { display:block; width:100%; height:112px; padding:16px; margin-bottom:20px; resize:none; border:1px solid var(--jz-rule);
|
|
62
|
+
border-radius:8px; background:var(--jz-surface); color:var(--jz-ink); font:inherit; }
|
|
63
|
+
.comment::placeholder { color:var(--jz-faint); }
|
|
64
|
+
.comment:focus { outline:none; box-shadow:0 0 0 1px var(--jz-accent); }
|
|
65
|
+
.foot { display:flex; align-items:center; justify-content:space-between; gap:12px; }
|
|
66
|
+
.shot { display:flex; align-items:center; gap:12px; min-width:0; }
|
|
67
|
+
.thumb { flex:none; width:80px; height:48px; border-radius:8px; border:1px solid var(--jz-rule); background:var(--jz-canvas);
|
|
68
|
+
overflow:hidden; display:flex; align-items:center; justify-content:center; color:var(--jz-faint); font-size:8px; }
|
|
69
|
+
.thumb img { width:100%; height:100%; object-fit:cover; }
|
|
70
|
+
.thumb.hatch { background:repeating-linear-gradient(45deg, rgb(138 144 153 / 10%) 0 4px, rgb(138 144 153 / 20%) 4px 8px); }
|
|
71
|
+
.shot-open { display:block; width:100%; height:100%; padding:0; border:0; background:transparent; }
|
|
72
|
+
.optout-row { display:flex; align-items:center; gap:8px; margin-bottom:16px; color:var(--jz-muted); font-size:12px; }
|
|
73
|
+
.optout-row[hidden] { display:none; }
|
|
74
|
+
.note { font-size:11px; color:var(--jz-faint); line-height:1.3; }
|
|
75
|
+
.shot-full { position:fixed; inset:0; z-index:2147483647; display:flex; align-items:center; justify-content:center; padding:24px; background:rgb(0 0 0 / 72%); }
|
|
76
|
+
.shot-full img { max-width:100%; max-height:100%; object-fit:contain; border-radius:6px; background:var(--jz-surface); }
|
|
77
|
+
.shot-full .close { position:absolute; top:16px; right:16px; background:var(--jz-surface); color:var(--jz-ink); }
|
|
78
|
+
.primary { min-height:44px; padding:0 24px; border:0; border-radius:8px; background:var(--jz-accent); color:var(--jz-accent-ink); font-weight:500; }
|
|
79
|
+
.primary:disabled { opacity:.45; cursor:not-allowed; }
|
|
80
|
+
.secondary { min-height:44px; padding:0 16px; border:1px solid var(--jz-rule); border-radius:6px; background:transparent;
|
|
81
|
+
color:var(--jz-muted); font-weight:500; }
|
|
82
|
+
|
|
83
|
+
.sheet { left:32px; bottom:32px; width:340px; max-width:calc(100vw - 32px); padding:24px; border-radius:10px; }
|
|
84
|
+
.sheet h2 { display:flex; align-items:center; gap:8px; margin:0 0 12px; font-size:14px; font-weight:500; }
|
|
85
|
+
.sheet h2 svg { color:var(--jz-accent); }
|
|
86
|
+
.sheet p { margin:0 0 12px; color:var(--jz-muted); line-height:1.6; }
|
|
87
|
+
.sheet ul { margin:0 0 20px; padding-left:18px; color:var(--jz-muted); }
|
|
88
|
+
.row { display:flex; gap:8px; }
|
|
89
|
+
.row > * { flex:1; }
|
|
90
|
+
|
|
91
|
+
.checkin { right:32px; bottom:140px; display:flex; align-items:center; gap:8px; padding:8px 8px 8px 16px; border-radius:10px; }
|
|
92
|
+
.checkin .secondary { min-height:36px; }
|
|
93
|
+
.toast { right:32px; bottom:88px; padding:10px 16px; border-radius:10px; }
|
|
94
|
+
.toast.err { border-color:var(--jz-broken); }
|
|
95
|
+
|
|
96
|
+
@media (max-width: 479px) {
|
|
97
|
+
.toggle { right:24px; bottom:24px; height:48px; padding:0 20px; background:var(--jz-accent); color:var(--jz-accent-ink); }
|
|
98
|
+
.toggle .dot { background:var(--jz-accent-ink); }
|
|
99
|
+
.toggle .exit { color:inherit; opacity:.8; }
|
|
100
|
+
.pop { left:0 !important; right:0; top:auto !important; bottom:0; width:auto; max-width:none; max-height:85vh;
|
|
101
|
+
border-radius:16px 16px 0 0; border-width:1px 0 0; padding:12px 24px 34px; }
|
|
102
|
+
.pop::before { content:""; display:block; width:48px; height:4px; margin:0 auto 16px; border-radius:999px; background:var(--jz-raised); }
|
|
103
|
+
.chip { border-radius:4px; border:1px solid var(--jz-rule); }
|
|
104
|
+
.reactions { display:grid; grid-template-columns:repeat(4, 1fr); gap:12px; border:0; overflow:visible; }
|
|
105
|
+
.reaction { border:1px solid var(--jz-rule); border-radius:8px; padding:16px 4px; }
|
|
106
|
+
.reaction:last-child { border-right:1px solid var(--jz-rule); }
|
|
107
|
+
.reaction[aria-checked="true"] { border:2px solid var(--jz-accent); }
|
|
108
|
+
.reaction span { font-size:11px; }
|
|
109
|
+
.foot { flex-direction:column; align-items:stretch; }
|
|
110
|
+
.foot .primary { width:100%; min-height:52px; font-size:15px; }
|
|
111
|
+
.sheet { left:16px; right:16px; bottom:16px; width:auto; }
|
|
112
|
+
.toast { left:16px; right:16px; bottom:84px; }
|
|
113
|
+
.checkin { left:16px; right:16px; bottom:136px; }
|
|
114
|
+
}
|
|
115
|
+
@media (prefers-reduced-motion: reduce) {
|
|
116
|
+
.jz *, .jz *::before, .jz *::after { animation-duration:1ms !important; transition-duration:1ms !important; }
|
|
117
|
+
}
|
|
118
|
+
`,ct=[["like","Like"],["dislike","Dislike"],["understood","Understood"],["confused","Confused"]],dt=5e3;function s(d,t={},...e){const o=document.createElement(d);for(const[i,r]of Object.entries(t))r===void 0||r===false||o.setAttribute(i,r===true?"":r);return o.append(...e),o}function ht(d,t,e,o){const i={pagePath:W(t),device:d.device||tt(e)},r=a=>{const c=d[a];typeof c=="string"&&c.trim()!==""&&(i[a]=c.trim())};return r("persona"),r("journeyId"),r("journeyStep"),r("businessType"),r("state"),o!==void 0&&(i.tflowId=o),i}class lt{constructor(t,e,o){n(this,"options");n(this,"getContext");n(this,"exit");n(this,"host",s("div",{"data-journeeze":""}));n(this,"root");n(this,"shell",s("div",{class:"jz"}));n(this,"layer",s("div",{class:"layer"}));n(this,"highlight",s("div",{class:"hl"}));n(this,"tag",s("div",{class:"tag mono"}));n(this,"live",s("div",{class:"sr","aria-live":"polite"}));n(this,"toggle");n(this,"channel");n(this,"outbox");n(this,"endpoint");n(this,"cleanups",[]);n(this,"phase","consent");n(this,"config",{});n(this,"pinCount",0);n(this,"popover");n(this,"fullShot");n(this,"fullShotOpener");n(this,"consentSheet");n(this,"checkin");n(this,"toastEl");n(this,"toastTimer");n(this,"lastCtx");n(this,"lastWhere");n(this,"askedSteps",new Set);n(this,"objectUrls",[]);n(this,"disposed",false);n(this,"exitTimer");n(this,"screenshotsUnavailable",false);n(this,"uploadNotFound",0);n(this,"pending",new Set);n(this,"signals");n(this,"configReady",Promise.resolve());n(this,"configLoaded",false);n(this,"maskAuditOn");this.options=t,this.getContext=e,this.exit=o,this.endpoint=K(t),this.signals=Z(t,this.endpoint,e),this.root=this.host.attachShadow({mode:"closed"}),this.root.append(s("style",t.nonce?{nonce:t.nonce}:{},at),this.shell),this.toggle=s("button",{type:"button",class:"toggle","aria-pressed":"true","aria-label":"Feedback mode on. Exit feedback mode"},s("span",{class:"dot","aria-hidden":"true"}),s("span",{},"Feedback mode on"),s("span",{class:"exit","aria-hidden":"true"},"· Exit")),this.toggle.addEventListener("click",()=>this.exit());for(const i of["keydown","keyup","keypress"])this.shell.addEventListener(i,r=>this.onWidgetKey(r));this.highlight.append(this.tag),this.layer.append(this.highlight),this.shell.append(this.layer,this.toggle,this.live),this.channel=it(t,this.endpoint,{beforePersist:()=>this.stashPending(),onDropped:i=>this.toast(pt(i),true)}),this.outbox=this.channel.outbox,document.body.append(this.host),this.listen(window,"keydown",i=>this.onKey(i)),this.lastCtx={...e()},this.lastWhere=j(),this.configReady=this.loadConfig(),this.maskAuditOn=!!t.reviewerToken&&nt(),this.maskAuditOn&&this.configReady.then(()=>this.maskAudit()),_(O(t))?this.startPointing():this.showConsent()}api(){return{unmount:t=>this.dispose(t),contextChanged:()=>this.onContextChanged()}}listen(t,e,o,i=false,r=false){t.addEventListener(e,o,{capture:i,passive:r}),this.cleanups.push(()=>t.removeEventListener(e,o,{capture:i}))}dispose(t){if(!this.disposed){this.disposed=true,this.signals.stop(t);for(const e of this.cleanups.splice(0))e();this.exitTimer!==void 0&&clearTimeout(this.exitTimer),this.stashPending(),this.channel.dispose(),this.toastTimer!==void 0&&clearTimeout(this.toastTimer);for(const e of this.objectUrls.splice(0))URL.revokeObjectURL(e);this.host.remove()}}async loadConfig(){try{if(this.config=await st(this.endpoint,this.options.siteKey),this.configLoaded=true,this.config.consentText&&this.consentSheet){const t=this.consentSheet.querySelector("p");t&&(t.textContent=this.config.consentText)}this.config.enabled!==true&&(this.toast("Feedback isn't switched on for this site yet.",true),this.exitTimer=setTimeout(()=>{this.disposed||this.exit()},2500))}catch(t){t instanceof M&&t.status===404&&(this.toast("Feedback isn't set up on this site yet.",true),this.exitTimer=setTimeout(()=>{this.disposed||this.exit()},2500))}}showConsent(){this.phase="consent";const t=s("h2",{id:"jz-consent-title"},m("info",18),"Suggest an improvement"),e=s("button",{type:"button",class:"primary"},"Allow and continue"),o=s("button",{type:"button",class:"secondary"},"Not now"),i=s("div",{class:"sheet",role:"dialog","aria-modal":"false","aria-labelledby":"jz-consent-title"},t,s("p",{},this.config.consentText||(this.screenshotsAllowed()?H:q)),s("div",{class:"row"},e,o));e.addEventListener("click",()=>{Y(O(this.options)),i.remove(),this.consentSheet=void 0,this.startPointing(),this.toggle.focus()}),o.addEventListener("click",()=>this.exit()),this.trapTab(i),this.consentSheet=i,this.shell.append(i),e.focus()}startPointing(){this.phase="pointing",this.signals.start(this.configReady.then(()=>this.config)),this.announce("Feedback mode on. Click any part of the page to comment on it. Press Escape to exit."),this.listen(document,"pointermove",t=>this.onMove(t),true,true);for(const t of["pointerdown","mousedown","mouseup","pointerup"])this.listen(window,t,e=>this.swallow(e),true);for(const t of["touchstart","touchend"])this.listen(window,t,e=>{this.phase==="pointing"&&this.targetOf(e)&&e.stopPropagation()},true,true);this.listen(window,"click",t=>this.onClick(t),true),this.listen(window,"scroll",()=>this.reposition(),true,true),this.listen(window,"resize",()=>this.reposition(),false,true),this.outbox.flush()}targetOf(t){const e=t.composedPath();if(e.includes(this.host))return;const o=e[0];return o instanceof Element?o:void 0}swallow(t){this.phase!=="pointing"||!t.isTrusted||!this.targetOf(t)||(t.preventDefault(),t.stopPropagation())}onMove(t){const e=this.phase==="pointing"?this.targetOf(t):void 0;if(!e){this.highlight.style.display="none";return}const o=e.getBoundingClientRect(),i=R(e)||I(e);Object.assign(this.highlight.style,{display:"block",left:`${o.left}px`,top:`${o.top}px`,width:`${o.width}px`,height:`${o.height}px`}),this.highlight.classList.toggle("masked",i),this.tag.textContent=i?"Masked":et(e),this.tag.style.top=o.top<20?"0":"-18px"}onClick(t){if(this.phase!=="pointing"||!t.isTrusted)return;const e=this.targetOf(t);e&&(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.highlight.style.display="none",!I(e)&&this.openPopover(e,t.clientX,t.clientY))}openPopover(t,e,o){this.phase="composing";const i=this.screenshotsUnavailable||!this.screenshotsAllowed()?Promise.resolve(void 0):this.configReady.then(()=>this.configLoaded?J(document.body,this.maskOptions()):void 0).catch(()=>{}),r=ot(t,e,o),a=s("div",{class:"pin","aria-hidden":"true"},String(++this.pinCount));let c;const h=s("h2",{id:"jz-pop-title"},"How does this feel?"),f=s("button",{type:"button",class:"close","aria-label":"Close without sending"},m("close")),x=s("div",{class:"chips"}),g=this.getContext(),D=j(),F=(l,u,p)=>x.append(s("span",{class:"chip","aria-label":`${u}: ${p}`},m(l,12),p));g.persona&&F("persona","Persona",g.persona),g.journeyStep&&F("step","Journey step",g.journeyStep);const C=s("div",{class:"reactions",role:"radiogroup","aria-label":"Reaction"}),E=ct.map(([l,u])=>{const p=s("button",{type:"button",class:"reaction",role:"radio","aria-checked":"false","data-r":l},m(l),s("span",{},u));return p.addEventListener("click",()=>{c=c===l?void 0:l;for(const L of E)L.setAttribute("aria-checked",String(L.dataset.r===c));z()}),C.append(p),p}),y=s("textarea",{class:"comment","aria-label":"Comment (optional)",placeholder:"What could be improved?",maxlength:"4000"}),v=s("div",{class:"thumb hatch mono"},"CAPTURING"),T=s("span",{class:"note"},"Masked fields are hidden"),A=s("input",{type:"checkbox",class:"optout"}),P=s("label",{class:"optout-row",hidden:true},A,"Don't include screenshot"),b=s("button",{type:"button",class:"primary"},"Send"),k=s("div",{class:"pop",role:"dialog","aria-modal":"false","aria-labelledby":"jz-pop-title"},s("div",{class:"pop-head"},h,f),x,C,y,P,s("div",{class:"foot"},s("div",{class:"shot"},v,T),b)),z=()=>{b.disabled=c===void 0&&y.value.trim()===""};y.addEventListener("input",z),z(),i.then(l=>{if(this.popover?.el===k)if(v.textContent="",l){const u=URL.createObjectURL(l);this.objectUrls.push(u),v.classList.remove("hatch");const p=s("button",{type:"button",class:"shot-open","aria-label":"View screenshot full size"},s("img",{referrerpolicy:"no-referrer",src:u,alt:"Screenshot of this page with masked fields hidden"}));p.addEventListener("click",()=>this.openFullShot(u,p)),v.append(p),P.hidden=false}else v.textContent="No screenshot attached",T.textContent="Screenshot unavailable; your feedback still sends"}),f.addEventListener("click",()=>this.closePopover()),b.addEventListener("click",()=>{if(b.disabled)return;b.disabled=true;const l=y.value.trim(),u=!A.checked;this.closePopover(),this.deliver(r,c,l,u?i:Promise.resolve(void 0),g,D)}),this.trapTab(k),this.popover={el:k,pin:a,target:t,anchor:r},this.layer.append(a),this.shell.append(k),this.reposition(),E[0]?.focus()}closePopover(){if(this.popover){this.closeFullShot(),this.popover.el.remove(),this.popover.pin.remove(),this.popover=void 0;for(const t of this.objectUrls.splice(0))URL.revokeObjectURL(t);this.phase="pointing",this.toggle.focus()}}openFullShot(t,e){if(this.fullShot)return;const o=s("button",{type:"button",class:"close","aria-label":"Close full-size screenshot"},m("close")),i=s("div",{class:"shot-full",role:"dialog","aria-modal":"true","aria-label":"Screenshot"},s("img",{referrerpolicy:"no-referrer",src:t,alt:"Screenshot of this page with masked fields hidden"}),o);o.addEventListener("click",()=>this.closeFullShot()),this.trapTab(i),this.fullShot=i,this.fullShotOpener=e,this.shell.append(i),o.focus()}closeFullShot(){const t=this.fullShot;if(!t)return;this.fullShot=void 0,t.remove();const e=this.fullShotOpener;this.fullShotOpener=void 0,e?.focus()}maskOptions(){const{maskSelectors:t,maskAllText:e}=this.options,o=Array.isArray(this.config.maskSelectors)?this.config.maskSelectors:[];return{...t?{maskSelectors:t}:{},...o.length?{configMaskSelectors:o}:{},...e?{maskAllText:e}:{}}}reposition(){const t=this.popover;if(!t||!t.target.isConnected)return;const e=t.target.getBoundingClientRect(),o=e.left+t.anchor.xRatio*e.width,i=e.top+t.anchor.yRatio*e.height;if(Object.assign(t.pin.style,{left:`${o}px`,top:`${i}px`}),window.innerWidth<480)return;const r=t.el.getBoundingClientRect(),a=16;let c=e.right+a;c+r.width>window.innerWidth-a&&(c=e.left-a-r.width),c<a&&(c=Math.min(Math.max(a,o+a),window.innerWidth-r.width-a));const h=Math.min(Math.max(a,i-24),window.innerHeight-r.height-a);Object.assign(t.el.style,{left:`${Math.max(a,c)}px`,top:`${Math.max(a,h)}px`})}maskAudit(){if(this.disposed||!this.configLoaded||this.config.enabled!==true||!this.options.reviewerToken)return;const t=[...this.options.maskSelectors??[],...Array.isArray(this.config.maskSelectors)?this.config.maskSelectors:[]],{endpoint:e}=this,{siteKey:o,reviewerToken:i}=this.options;import("./mask-audit-Du3NPoG_.js").then(r=>this.disposed?0:r.runMaskAudit({scan:V,endpoint:e,siteKey:o,reviewerToken:i,maskSelectors:t})).catch(()=>{})}onContextChanged(){this.signals.contextChanged(),this.maskAuditOn&&this.maskAudit();const t=this.getContext();if(t.journeyStep===this.lastCtx.journeyStep&&t.journeyId===this.lastCtx.journeyId)return;const e=this.lastCtx,o=this.lastWhere;this.lastCtx={...t},this.lastWhere=j(),this.checkin?.remove(),this.checkin=void 0,this.maybeCheckin(e,o)}maybeCheckin(t,e){const o=t,i=o.journeyStep;if(this.phase==="consent"||!i)return;const r=`${o.journeyId??""}/${i}`;if(this.askedSteps.has(r))return;this.askedSteps.add(r),this.checkin?.remove();const a=(f,x)=>{const g=s("button",{type:"button",class:"secondary"},m(f,16),x);return g.addEventListener("click",()=>{h.remove(),this.deliver(void 0,f,"",Promise.resolve(void 0),t,e)}),g},c=s("button",{type:"button",class:"close","aria-label":"Dismiss"},m("close",16)),h=s("div",{class:"checkin",role:"group","aria-label":"Step check-in"},s("span",{},"Did this step make sense?"),a("understood","Understood"),a("confused","Confused"),c);c.addEventListener("click",()=>h.remove()),this.checkin=h,this.shell.append(h)}async deliver(t,e,o,i,r=this.getContext(),a=j()){const c={siteKey:this.options.siteKey,consentGiven:true,context:ht(r,a.href,a.width,t?.tflowId)};this.options.userId!==void 0&&Object.assign(c,{userId:this.options.userId},G(this.options)),t&&(c.anchor=t),e&&(c.reaction=Q[e]),o&&(c.comment=o);const h={request:c,stashed:false};this.pending.add(h);const f=await this.uploadScreenshot(i);if(this.pending.delete(h),h.stashed||this.disposed)return;f&&(c.screenshotId=f);const x=await this.outbox.enqueue(c);this.disposed||(x==="sent"?this.toast("Sent. Thank you."):x==="queued"&&this.toast("Saved. It will send when you're back online."))}stashPending(){for(const t of this.pending)t.stashed=true,this.outbox.stash(t.request);this.pending.clear()}screenshotsAllowed(){return!!(this.options.reviewerToken||this.options.userId)}async uploadScreenshot(t){if(!this.screenshotsUnavailable)try{let e;const o=await Promise.race([t,new Promise(r=>e=setTimeout(()=>r(void 0),dt))]).finally(()=>clearTimeout(e));if(!o)return;const i=await X(this.endpoint,this.options,o);return this.uploadNotFound=0,i}catch(e){e instanceof M&&(this.uploadNotFound=e.status===404?this.uploadNotFound+1:0,(e.code==="unimplemented"||this.uploadNotFound>=3)&&(this.screenshotsUnavailable=true));return}}onKey(t){if(t.key!=="Escape")return;const e=t.composedPath()[0];if(t.defaultPrevented||e instanceof Element&&R(e))return;const o=document.activeElement;o&&o!==document.body&&o!==document.documentElement&&o!==this.host||(this.popover?this.closePopover():this.exit())}onWidgetKey(t){if(t.stopPropagation(),t.type!=="keydown"||t.key!=="Escape")return;if(this.fullShot){this.closeFullShot();return}const e=t.target;if(e instanceof HTMLTextAreaElement&&e.value.trim()!==""&&this.popover){this.popover.el.querySelector(".close")?.focus();return}this.popover?this.closePopover():this.exit()}trapTab(t){t.addEventListener("keydown",e=>{if(e.key!=="Tab")return;const o=Array.from(t.querySelectorAll("button:not([disabled]), textarea")),i=o[0],r=o[o.length-1],a=this.root.activeElement;!i||!r||(e.shiftKey&&a===i?(e.preventDefault(),r.focus()):!e.shiftKey&&a===r&&(e.preventDefault(),i.focus()))})}announce(t){this.live.textContent=t}toast(t,e=false){this.toastEl?.remove(),this.toastTimer!==void 0&&clearTimeout(this.toastTimer);const o=s("div",{class:e?"toast err":"toast",role:"status"},t);this.toastEl=o,this.shell.append(o),this.toastTimer=setTimeout(()=>o.remove(),e?6e3:3e3)}}function j(){return{href:location.href,width:window.innerWidth}}function pt(d){return d.code==="unauthenticated"?"Open the review link from your invitation to send feedback.":d.code==="failed_precondition"?"Consent is needed before feedback can be sent.":"This feedback couldn't be sent."}const yt=(d,t,e)=>new lt(d,()=>B(t()),e).api();export{jt as maskedSnapshotSvg,yt as mount,G as signedIdentity,zt as uploadTarget,ht as wireContext};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@journeeze/sdk",
|
|
3
|
-
"version": "0.1.0-rc.
|
|
3
|
+
"version": "0.1.0-rc.3",
|
|
4
4
|
"description": "Journeeze feedback mode: a tiny loader that lazy-loads the widget when the mode is switched on.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"publishConfig": {
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
"test": "vitest run",
|
|
38
38
|
"prepublishOnly": "node -e \"const fs=require('fs');for(const f of ['dist/index.js','dist/types/index.d.ts'])if(!fs.existsSync(f)){console.error('prepublishOnly: missing '+f+' - run npm run build first');process.exit(1)}\"",
|
|
39
39
|
"build": "vite build && tsc -p tsconfig.build.json && node --import tsx scripts/check-size.ts",
|
|
40
|
-
"test:e2e": "vite build && playwright install chromium && playwright test"
|
|
40
|
+
"test:e2e": "vite build && playwright install chromium && playwright test",
|
|
41
|
+
"test:e2e:real": "vite build && playwright install chromium && playwright test -c e2e/real/playwright.config.ts"
|
|
41
42
|
},
|
|
42
43
|
"peerDependencies": {
|
|
43
44
|
"react": ">=18",
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
}
|
|
53
54
|
},
|
|
54
55
|
"devDependencies": {
|
|
56
|
+
"@axe-core/playwright": "^4.13.0",
|
|
55
57
|
"@babel/parser": "^7.29.9",
|
|
56
58
|
"@playwright/test": "^1.63.0",
|
|
57
59
|
"@types/react": "^19.2.0",
|
package/dist/consent-CoKD33Rm.js
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
var g = Object.defineProperty;
|
|
2
|
-
var T = (e, t, n) => t in e ? g(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
|
|
3
|
-
var u = (e, t, n) => T(e, typeof t != "symbol" ? t + "" : t, n);
|
|
4
|
-
import { CONTEXT_FIELDS as w, CONTEXT_VALUE_MAX_LEN as S, CONTEXT_ID_PATTERN as N, API_PATH_PATTERN as _ } from "./contract.js";
|
|
5
|
-
import { p as E } from "./context-UnG6_X61.js";
|
|
6
|
-
import { w as c } from "./loader-Ba4X-WNl.js";
|
|
7
|
-
class m extends Error {
|
|
8
|
-
constructor(n, o, r = 0, i) {
|
|
9
|
-
super(o);
|
|
10
|
-
u(this, "code");
|
|
11
|
-
u(this, "status");
|
|
12
|
-
u(this, "retryAfterMs");
|
|
13
|
-
this.code = n, this.status = r, this.retryAfterMs = i;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
const C = "https://app.journeeze.dev", b = 15e3;
|
|
17
|
-
function k(e, t = b) {
|
|
18
|
-
return typeof AbortSignal < "u" && typeof AbortSignal.timeout == "function" ? { ...e, signal: AbortSignal.timeout(t) } : e;
|
|
19
|
-
}
|
|
20
|
-
function O(e, t = location.href) {
|
|
21
|
-
try {
|
|
22
|
-
return new URL(e, t).origin !== new URL(t).origin;
|
|
23
|
-
} catch {
|
|
24
|
-
return !0;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
const $ = "text/plain;charset=UTF-8";
|
|
28
|
-
function A(e, t) {
|
|
29
|
-
return `${e.replace(/\/+$/, "")}/journeeze.collector.v1.CollectorService/${t}`;
|
|
30
|
-
}
|
|
31
|
-
function I(e, t) {
|
|
32
|
-
const n = O(e) ? { "content-type": $ } : { "content-type": "application/json", "connect-protocol-version": "1" };
|
|
33
|
-
return t ? { ...n, "if-none-match": t } : n;
|
|
34
|
-
}
|
|
35
|
-
function y(e, t, n, o, r) {
|
|
36
|
-
const i = k({
|
|
37
|
-
method: "POST",
|
|
38
|
-
headers: I(e, r.etag),
|
|
39
|
-
body: JSON.stringify(n),
|
|
40
|
-
credentials: "omit",
|
|
41
|
-
cache: "no-store",
|
|
42
|
-
referrerPolicy: "no-referrer",
|
|
43
|
-
...r.keepalive ? { keepalive: !0 } : {}
|
|
44
|
-
});
|
|
45
|
-
return o(A(e, t), i);
|
|
46
|
-
}
|
|
47
|
-
const j = 6e4;
|
|
48
|
-
function M(e, t = Date.now()) {
|
|
49
|
-
if (!e) return;
|
|
50
|
-
const n = Number(e.trim()), o = Number.isFinite(n) && /^\d+$/.test(e.trim()) ? n * 1e3 : Date.parse(e) - t;
|
|
51
|
-
return Number.isFinite(o) ? Math.min(Math.max(o, 0), j) : void 0;
|
|
52
|
-
}
|
|
53
|
-
async function v(e) {
|
|
54
|
-
const t = await e.json().catch(() => {
|
|
55
|
-
});
|
|
56
|
-
if (!e.ok) {
|
|
57
|
-
const n = typeof t?.code == "string" ? t.code : P(e.status);
|
|
58
|
-
throw new m(n, String(t?.message ?? e.statusText), e.status, M(e.headers.get("retry-after")));
|
|
59
|
-
}
|
|
60
|
-
if (t === void 0 || typeof t != "object" || t === null)
|
|
61
|
-
throw new m("unavailable", "the collector did not answer with Connect JSON", e.status);
|
|
62
|
-
return t;
|
|
63
|
-
}
|
|
64
|
-
async function F(e, t, n, o = fetch, r = {}) {
|
|
65
|
-
return v(await y(e, t, n, o, r.keepalive ? { keepalive: !0 } : {}));
|
|
66
|
-
}
|
|
67
|
-
async function H(e, t, n, o, r = fetch) {
|
|
68
|
-
const i = await y(e, t, n, r, o ? { etag: o } : {});
|
|
69
|
-
if (i.status === 304) return { notModified: !0 };
|
|
70
|
-
const s = await v(i), a = i.headers.get("etag");
|
|
71
|
-
return a ? { notModified: !1, value: s, etag: a } : { notModified: !1, value: s };
|
|
72
|
-
}
|
|
73
|
-
function X(e, t) {
|
|
74
|
-
return t ? `${e.replace(/\/+$/, "")}${t.startsWith("/") ? "" : "/"}${t}` : void 0;
|
|
75
|
-
}
|
|
76
|
-
function P(e) {
|
|
77
|
-
return e === 401 ? "unauthenticated" : e === 403 ? "permission_denied" : e === 409 ? "already_exists" : e === 412 ? "failed_precondition" : e === 429 ? "resource_exhausted" : e === 404 || e === 408 || e >= 500 ? "unavailable" : e >= 400 ? "invalid_argument" : "unknown";
|
|
78
|
-
}
|
|
79
|
-
function J(e, t = location.href) {
|
|
80
|
-
const { endpoint: n, apiHost: o, apiPath: r } = e;
|
|
81
|
-
if (n !== void 0)
|
|
82
|
-
return c("endpoint is deprecated; use apiHost"), new URL(n, t).href.replace(/\/+$/, "");
|
|
83
|
-
let i = C;
|
|
84
|
-
if (o !== void 0) {
|
|
85
|
-
const s = o.replace(/\/$/, "");
|
|
86
|
-
let a = !1;
|
|
87
|
-
try {
|
|
88
|
-
const f = new URL(s);
|
|
89
|
-
a = f.origin === s && (f.protocol === "https:" || /^(localhost|127\.0\.0\.1)$/.test(f.hostname));
|
|
90
|
-
} catch {
|
|
91
|
-
}
|
|
92
|
-
a ? i = s : c("invalid apiHost ignored");
|
|
93
|
-
}
|
|
94
|
-
return r === void 0 ? i : _.test(r) ? i + r : (c("invalid apiPath ignored"), i);
|
|
95
|
-
}
|
|
96
|
-
function z(e) {
|
|
97
|
-
const t = {};
|
|
98
|
-
for (const n of w) {
|
|
99
|
-
if (!(n in e)) continue;
|
|
100
|
-
const o = e[n] || void 0;
|
|
101
|
-
if (o !== void 0 && (typeof o != "string" || o.length > S || /[\0-\x1f\x7f]/.test(o))) {
|
|
102
|
-
c(`context.${n} dropped (1..=128 printable characters)`), t[n] = void 0;
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
o !== void 0 && !N.test(o) && c(`context.${n} should be an id`), t[n] = o;
|
|
106
|
-
}
|
|
107
|
-
return t;
|
|
108
|
-
}
|
|
109
|
-
const R = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$|[0-9a-f]{16}|@|^[\w-]{24,}$/i;
|
|
110
|
-
function Y(e) {
|
|
111
|
-
return E(e).split("/").map((t) => {
|
|
112
|
-
let n = t;
|
|
113
|
-
try {
|
|
114
|
-
n = decodeURIComponent(t);
|
|
115
|
-
} catch {
|
|
116
|
-
}
|
|
117
|
-
return R.test(n) ? ":id" : t;
|
|
118
|
-
}).join("/");
|
|
119
|
-
}
|
|
120
|
-
const d = 1, q = "Feedback mode captures the element you point at, a screenshot of this page with form fields hidden, your comment, and your persona and journey step. It never records keystrokes, form contents or query strings. Your feedback is visible to the project's review team.", V = "Feedback mode captures the element you point at, your comment, and your persona and journey step. No screenshot is sent. It never records keystrokes, form contents or query strings. Your feedback is visible to the project's review team.", l = (e) => `jz:consent:v${d}:${e}`, p = /* @__PURE__ */ new Set(), B = (e) => e.userId ? `${e.siteKey}:u:${e.userId}` : e.siteKey;
|
|
121
|
-
function G(e, t = h()) {
|
|
122
|
-
p.delete(e);
|
|
123
|
-
try {
|
|
124
|
-
t?.removeItem(l(e));
|
|
125
|
-
} catch {
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
function h() {
|
|
129
|
-
try {
|
|
130
|
-
return window.localStorage;
|
|
131
|
-
} catch {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
function K(e, t = h()) {
|
|
136
|
-
if (p.has(e)) return !0;
|
|
137
|
-
try {
|
|
138
|
-
const n = t?.getItem(l(e));
|
|
139
|
-
return n ? JSON.parse(n).v === d : !1;
|
|
140
|
-
} catch {
|
|
141
|
-
return !1;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
function W(e, t = h()) {
|
|
145
|
-
p.add(e);
|
|
146
|
-
try {
|
|
147
|
-
t?.setItem(l(e), JSON.stringify({ v: d, at: (/* @__PURE__ */ new Date()).toISOString() }));
|
|
148
|
-
} catch {
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
export {
|
|
152
|
-
m as C,
|
|
153
|
-
q as D,
|
|
154
|
-
j as R,
|
|
155
|
-
$ as T,
|
|
156
|
-
G as a,
|
|
157
|
-
J as b,
|
|
158
|
-
F as c,
|
|
159
|
-
z as d,
|
|
160
|
-
Y as e,
|
|
161
|
-
B as f,
|
|
162
|
-
V as g,
|
|
163
|
-
K as h,
|
|
164
|
-
W as i,
|
|
165
|
-
H as j,
|
|
166
|
-
X as k,
|
|
167
|
-
A as r,
|
|
168
|
-
h as s,
|
|
169
|
-
k as w
|
|
170
|
-
};
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
var E = Object.defineProperty;
|
|
2
|
-
var I = (s, e, t) => e in s ? E(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
|
|
3
|
-
var d = (s, e, t) => I(s, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
-
import { C as w, s as v, c as f, a as _, b as q } from "./consent-CoKD33Rm.js";
|
|
5
|
-
const x = /* @__PURE__ */ new Set(["invalid_argument", "failed_precondition", "permission_denied", "unauthenticated", "not_found", "already_exists", "unimplemented"]), g = 50, A = 1e3, O = 6e4, y = 1440 * 60 * 1e3;
|
|
6
|
-
function T(s) {
|
|
7
|
-
return Math.min(O, A * 2 ** Math.max(0, s));
|
|
8
|
-
}
|
|
9
|
-
function L(s) {
|
|
10
|
-
return s instanceof w && x.has(s.code);
|
|
11
|
-
}
|
|
12
|
-
class M {
|
|
13
|
-
constructor(e) {
|
|
14
|
-
d(this, "deps");
|
|
15
|
-
d(this, "items", []);
|
|
16
|
-
d(this, "inFlight");
|
|
17
|
-
d(this, "attempt", 0);
|
|
18
|
-
d(this, "flushing");
|
|
19
|
-
d(this, "timer");
|
|
20
|
-
d(this, "disposed", !1);
|
|
21
|
-
d(this, "schedule");
|
|
22
|
-
d(this, "cancel");
|
|
23
|
-
d(this, "now");
|
|
24
|
-
this.deps = e, this.schedule = e.schedule ?? ((t, i) => setTimeout(t, i)), this.cancel = e.cancel ?? ((t) => clearTimeout(t)), this.now = e.now ?? Date.now, this.claim();
|
|
25
|
-
}
|
|
26
|
-
get size() {
|
|
27
|
-
return this.items.length;
|
|
28
|
-
}
|
|
29
|
-
enqueue(e) {
|
|
30
|
-
return new Promise((t) => {
|
|
31
|
-
const i = { request: e, settle: t };
|
|
32
|
-
this.add(i), this.flush().then(() => {
|
|
33
|
-
this.items.includes(i) && u(i, "queued");
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
stash(e) {
|
|
38
|
-
this.add({ request: e });
|
|
39
|
-
}
|
|
40
|
-
flush() {
|
|
41
|
-
return this.disposed ? Promise.resolve() : (this.timer !== void 0 && (this.cancel(this.timer), this.timer = void 0), this.flushing ? this.flushing.then(() => this.timer === void 0 ? this.flush() : void 0) : (this.flushing = this.drain().finally(() => {
|
|
42
|
-
this.flushing = void 0;
|
|
43
|
-
}), this.flushing));
|
|
44
|
-
}
|
|
45
|
-
persist() {
|
|
46
|
-
const e = this.items.filter((t) => t !== this.inFlight);
|
|
47
|
-
if (!(e.length === 0 || !this.deps.storage))
|
|
48
|
-
try {
|
|
49
|
-
const t = this.read(), i = this.now(), n = this.deps.user?.(), c = [...t, ...e.map((r) => ({ owner: this.deps.owner, request: r.request, at: r.at ?? i, ...n ? { user: n } : {} }))].slice(-g);
|
|
50
|
-
this.deps.storage?.setItem(this.deps.storageKey, JSON.stringify(c));
|
|
51
|
-
for (const r of e) u(r, "queued");
|
|
52
|
-
this.items = this.items.filter((r) => r === this.inFlight);
|
|
53
|
-
} catch {
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
claim() {
|
|
57
|
-
try {
|
|
58
|
-
const e = this.read(), t = e.filter((n) => n.owner === this.deps.owner);
|
|
59
|
-
if (t.length === 0) return;
|
|
60
|
-
const i = e.filter((n) => n.owner !== this.deps.owner);
|
|
61
|
-
i.length === 0 ? this.deps.storage?.removeItem(this.deps.storageKey) : this.deps.storage?.setItem(this.deps.storageKey, JSON.stringify(i));
|
|
62
|
-
for (const n of t) this.fresh(n) && this.add({ request: n.request, at: n.at });
|
|
63
|
-
} catch {
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
dispose() {
|
|
67
|
-
this.persist(), this.disposed = !0, this.timer !== void 0 && this.cancel(this.timer), this.timer = void 0;
|
|
68
|
-
}
|
|
69
|
-
add(e) {
|
|
70
|
-
var t;
|
|
71
|
-
for ((t = e.request).submissionId ?? (t.submissionId = F()), this.items.push(e); this.items.length > g; ) {
|
|
72
|
-
const i = this.items[0] === this.inFlight ? 1 : 0, [n] = this.items.splice(i, 1);
|
|
73
|
-
n && u(n, "dropped");
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
async drain() {
|
|
77
|
-
for (; !this.disposed; ) {
|
|
78
|
-
const e = this.items[0];
|
|
79
|
-
if (!e) {
|
|
80
|
-
this.attempt = 0;
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
this.inFlight = e;
|
|
84
|
-
try {
|
|
85
|
-
await this.deps.send(e.request), this.remove(e), this.attempt = 0, u(e, "sent");
|
|
86
|
-
} catch (t) {
|
|
87
|
-
if (L(t)) {
|
|
88
|
-
this.remove(e), u(e, "dropped"), this.deps.onDropped?.(t);
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
if (this.disposed) {
|
|
92
|
-
this.inFlight = void 0, this.persist();
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
const i = T(this.attempt++);
|
|
96
|
-
this.timer = this.schedule(() => {
|
|
97
|
-
this.timer = void 0, this.flush();
|
|
98
|
-
}, i);
|
|
99
|
-
return;
|
|
100
|
-
} finally {
|
|
101
|
-
this.inFlight = void 0;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
fresh(e) {
|
|
106
|
-
return e.at === void 0 ? !0 : typeof e.at == "number" && Number.isFinite(e.at) && this.now() - e.at <= y;
|
|
107
|
-
}
|
|
108
|
-
remove(e) {
|
|
109
|
-
const t = this.items.indexOf(e);
|
|
110
|
-
t >= 0 && this.items.splice(t, 1);
|
|
111
|
-
}
|
|
112
|
-
read() {
|
|
113
|
-
const e = this.deps.storage?.getItem(this.deps.storageKey), t = e ? JSON.parse(e) : [];
|
|
114
|
-
return Array.isArray(t) ? t.filter(
|
|
115
|
-
(i) => typeof i == "object" && i !== null && typeof i.owner == "string" && typeof i.request == "object" && i.request !== null
|
|
116
|
-
) : [];
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
function D(s) {
|
|
120
|
-
if (!s) return "";
|
|
121
|
-
let e = 2166136261;
|
|
122
|
-
for (let t = 0; t < s.length; t++)
|
|
123
|
-
e ^= s.charCodeAt(t), e = Math.imul(e, 16777619) >>> 0;
|
|
124
|
-
return e.toString(16).padStart(8, "0");
|
|
125
|
-
}
|
|
126
|
-
function F() {
|
|
127
|
-
return crypto.randomUUID();
|
|
128
|
-
}
|
|
129
|
-
function u(s, e) {
|
|
130
|
-
const t = s.settle;
|
|
131
|
-
s.settle = void 0, t?.(e);
|
|
132
|
-
}
|
|
133
|
-
function P(s, e, t, i = Date.now()) {
|
|
134
|
-
try {
|
|
135
|
-
const n = s?.getItem(e), c = n ? JSON.parse(n) : [], r = Array.isArray(c) ? c : [], a = r.filter((o) => o?.owner === t), h = r.filter((o) => o?.owner !== t);
|
|
136
|
-
return h.length === 0 ? s?.removeItem(e) : s?.setItem(e, JSON.stringify(h)), a.filter((o) => o.request && (o.at === void 0 || i - o.at <= y)).sort((o, l) => (o.at ?? 0) - (l.at ?? 0)).map((o) => o.request);
|
|
137
|
-
} catch {
|
|
138
|
-
return [];
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
const b = (s) => D(s.reviewerToken || (s.userId ? `u:${s.userId}` : void 0)), N = 32 * 1024;
|
|
142
|
-
async function k(s) {
|
|
143
|
-
const e = P(v(), `jz:outbox:v2:${s.siteKey}`, b(s));
|
|
144
|
-
if (_(s.siteKey), e.length === 0) return;
|
|
145
|
-
const t = q(s);
|
|
146
|
-
let i = N;
|
|
147
|
-
const n = (a, h) => f(t, "SubmitFeedback", a, fetch, { keepalive: h }), r = (await Promise.allSettled(
|
|
148
|
-
e.map((a) => {
|
|
149
|
-
const h = S(s, a), o = new Blob([JSON.stringify(h)]).size, l = o <= i;
|
|
150
|
-
l && (i -= o);
|
|
151
|
-
const m = n(h, l);
|
|
152
|
-
return l ? m.catch((p) => p instanceof w ? Promise.reject(p) : n(h, !1)) : m;
|
|
153
|
-
})
|
|
154
|
-
)).filter((a) => a.status === "rejected").length;
|
|
155
|
-
r && console.warn(`[journeeze] ${r} feedback item(s) could not be sent at logout and were discarded`);
|
|
156
|
-
}
|
|
157
|
-
function S(s, e) {
|
|
158
|
-
const t = s.reviewerToken ? { ...e, reviewerToken: s.reviewerToken } : { ...e };
|
|
159
|
-
if (s.pagePath === "none") {
|
|
160
|
-
const { pagePath: i, ...n } = t.context;
|
|
161
|
-
t.context = n;
|
|
162
|
-
}
|
|
163
|
-
return t;
|
|
164
|
-
}
|
|
165
|
-
function K(s, e, t = {}) {
|
|
166
|
-
const i = (h) => f(e, "SubmitFeedback", S(s, h), fetch, { keepalive: !0 }).then(() => {
|
|
167
|
-
}), n = new M({
|
|
168
|
-
send: i,
|
|
169
|
-
storage: t.memoryOnly ? void 0 : v(),
|
|
170
|
-
storageKey: `jz:outbox:v2:${s.siteKey}`,
|
|
171
|
-
owner: b(s),
|
|
172
|
-
user: () => s.userId,
|
|
173
|
-
...t.onDropped ? { onDropped: t.onDropped } : {}
|
|
174
|
-
}), c = () => {
|
|
175
|
-
n.flush();
|
|
176
|
-
}, r = () => {
|
|
177
|
-
t.beforePersist?.(), n.persist();
|
|
178
|
-
}, a = (h) => {
|
|
179
|
-
h.persisted && (n.claim(), n.flush());
|
|
180
|
-
};
|
|
181
|
-
return window.addEventListener("online", c), window.addEventListener("pagehide", r), window.addEventListener("pageshow", a), {
|
|
182
|
-
outbox: n,
|
|
183
|
-
dispose() {
|
|
184
|
-
window.removeEventListener("online", c), window.removeEventListener("pagehide", r), window.removeEventListener("pageshow", a), n.dispose();
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
function z(s, e) {
|
|
189
|
-
return f(s, "GetWidgetConfig", { siteKey: e });
|
|
190
|
-
}
|
|
191
|
-
export {
|
|
192
|
-
K as feedbackChannel,
|
|
193
|
-
k as logout,
|
|
194
|
-
b as ownerOf,
|
|
195
|
-
z as widgetConfig
|
|
196
|
-
};
|