@harkly/js 0.1.0 → 0.2.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/generated/api-types.d.ts +2 -2
- package/dist/harkly.iife.js +7 -3
- package/dist/index.d.ts +15 -1
- package/dist/index.js +8 -4
- package/dist/index.js.map +6 -5
- package/dist/surveys.d.ts +19 -0
- package/dist/widgets.d.ts +5 -1
- package/package.json +1 -1
|
@@ -4349,7 +4349,7 @@ export interface operations {
|
|
|
4349
4349
|
url: string;
|
|
4350
4350
|
description?: string | null;
|
|
4351
4351
|
/** @default [] */
|
|
4352
|
-
events?: ("post.created" | "post.status_changed" | "post.merged" | "post.deleted" | "vote.added" | "vote.removed" | "comment.created" | "changelog.published" | "end_user.identified" | "company.upserted" | "end_user.deleted" | "moderation.decided" | "member.joined" | "conversation.created" | "conversation.updated" | "message.created")[];
|
|
4352
|
+
events?: ("post.created" | "post.status_changed" | "post.merged" | "post.deleted" | "vote.added" | "vote.removed" | "comment.created" | "changelog.published" | "end_user.identified" | "company.upserted" | "end_user.deleted" | "moderation.decided" | "member.joined" | "conversation.created" | "conversation.updated" | "message.created" | "workflow.published" | "survey.completed")[];
|
|
4353
4353
|
active?: boolean;
|
|
4354
4354
|
};
|
|
4355
4355
|
};
|
|
@@ -4502,7 +4502,7 @@ export interface operations {
|
|
|
4502
4502
|
url?: string;
|
|
4503
4503
|
description?: string | null;
|
|
4504
4504
|
/** @default [] */
|
|
4505
|
-
events?: ("post.created" | "post.status_changed" | "post.merged" | "post.deleted" | "vote.added" | "vote.removed" | "comment.created" | "changelog.published" | "end_user.identified" | "company.upserted" | "end_user.deleted" | "moderation.decided" | "member.joined" | "conversation.created" | "conversation.updated" | "message.created")[];
|
|
4505
|
+
events?: ("post.created" | "post.status_changed" | "post.merged" | "post.deleted" | "vote.added" | "vote.removed" | "comment.created" | "changelog.published" | "end_user.identified" | "company.upserted" | "end_user.deleted" | "moderation.decided" | "member.joined" | "conversation.created" | "conversation.updated" | "message.created" | "workflow.published" | "survey.completed")[];
|
|
4506
4506
|
active?: boolean;
|
|
4507
4507
|
};
|
|
4508
4508
|
};
|
package/dist/harkly.iife.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(()=>{var
|
|
1
|
+
(()=>{var J=Object.defineProperty;var Q=(e,y)=>{for(var t in y)J(e,t,{get:y[t],enumerable:!0,configurable:!0,set:(r)=>y[t]=()=>r})};var N={};Q(N,{updates:()=>s,unread:()=>o,surveys:()=>ye,survey:()=>te,reset:()=>c,messenger:()=>ee,init:()=>u,identify:()=>d,feedback:()=>p,HarklyClient:()=>F});function H(e,y,t,r){let k=new URL(`/widget/${y}`,e);for(let[h,f]of Object.entries(t))if(f)k.searchParams.set(h,f);let a=new URLSearchParams;if(r.jwt)a.set("jwt",r.jwt);if(r.anonymousId)a.set("anon",r.anonymousId);let l=a.toString();return l?`${k.toString()}#${l}`:k.toString()}function W(e){if(!e||typeof e!=="object")return null;let y=e;if(y.type==="harkly:close")return{type:"harkly:close"};if(y.type==="harkly:posted"&&typeof y.postId==="string")return{type:"harkly:posted",postId:y.postId};if(y.type==="harkly:height"&&typeof y.height==="number")return{type:"harkly:height",height:y.height};if(y.type==="harkly:survey"&&(y.status==="completed"||y.status==="dismissed"||y.status==="none"))return{type:"harkly:survey",status:y.status};return null}var B="harkly-widget-style",X=`
|
|
2
2
|
.harkly-overlay{position:fixed;inset:0;z-index:2147483000;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:16px;opacity:0;transition:opacity .18s ease}
|
|
3
3
|
.harkly-overlay[data-open]{opacity:1}
|
|
4
4
|
.harkly-frame{border:0;width:min(560px,100%);height:min(640px,100%);border-radius:14px;background:transparent;box-shadow:0 24px 64px rgba(0,0,0,.35);transform:translateY(8px) scale(.98);transition:transform .22s cubic-bezier(.22,1,.36,1)}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
.harkly-overlay[data-side] {justify-content:flex-end;padding:0}
|
|
7
7
|
.harkly-overlay[data-side] .harkly-frame{width:min(420px,100%);height:100%;border-radius:0;transform:translateX(24px)}
|
|
8
8
|
.harkly-overlay[data-side][data-open] .harkly-frame{transform:none}
|
|
9
|
-
@media (prefers-reduced-motion: reduce){.harkly-overlay,.harkly-frame{transition:none}}`;function
|
|
9
|
+
@media (prefers-reduced-motion: reduce){.harkly-overlay,.harkly-frame{transition:none}}`;function Z(e){if(e.getElementById(B))return;let y=e.createElement("style");y.id=B,y.textContent=X,e.head.appendChild(y)}function g(e,y,t,r){Z(e);let k=e.createElement("div");if(k.className="harkly-overlay",r.side)k.dataset.side="";let a=e.createElement("iframe");a.className="harkly-frame",a.src=y,a.title="Harkly",a.setAttribute("allow","clipboard-write"),k.appendChild(a);let l=e.activeElement,h=()=>{e.defaultView?.removeEventListener("message",f),e.removeEventListener("keydown",b),k.removeAttribute("data-open"),setTimeout(()=>k.remove(),200),l?.focus?.(),r.onClose?.()},f=(w)=>{if(w.origin!==t||w.source!==a.contentWindow)return;let m=W(w.data);if(!m)return;if(m.type==="harkly:close")h();if(m.type==="harkly:posted")r.onPosted?.(m.postId);if(m.type==="harkly:survey")if(r.onSurvey?.(m.status),m.status==="completed")setTimeout(h,2500);else h()},b=(w)=>{if(w.key==="Escape")h()};return k.addEventListener("click",(w)=>{if(w.target===k)h()}),e.defaultView?.addEventListener("message",f),e.addEventListener("keydown",b),e.body.appendChild(k),e.defaultView?.requestAnimationFrame(()=>{k.dataset.open="",a.focus()}),{close:h}}function M(e){let y=e.replace(/[.+^${}()|[\]\\]/g,"\\$&").split("**").map((t)=>t.replace(/\*/g,"[^/]*")).join(".*");return new RegExp(`^${y}/?$`)}function v(e,y){if(!y||y.mode==="all"||y.patterns.length===0)return!0;let t=y.patterns.some((r)=>M(r).test(e));return y.mode==="include"?t:!t}function O(e,y){if(!y)return e;return{position:e.position??y.position,color:e.color??y.color??void 0,launcher:e.launcher??y.launcher,theme:e.theme}}var C="harkly-messenger-style",K=`
|
|
10
10
|
.harkly-launcher{position:fixed;bottom:20px;z-index:2147483000;width:52px;height:52px;border:0;border-radius:50%;cursor:pointer;color:#fff;background:var(--harkly-color,#111);box-shadow:0 8px 24px rgba(0,0,0,.22);display:flex;align-items:center;justify-content:center;transition:transform .18s ease}
|
|
11
11
|
.harkly-launcher:hover{transform:scale(1.05)}
|
|
12
12
|
.harkly-launcher[data-side=right]{right:20px}.harkly-launcher[data-side=left]{left:20px}
|
|
@@ -18,4 +18,8 @@
|
|
|
18
18
|
.harkly-messenger[data-side=right]{right:20px}.harkly-messenger[data-side=left]{left:20px;transform-origin:bottom left}
|
|
19
19
|
.harkly-messenger[data-open]{opacity:1;pointer-events:auto;transform:none}
|
|
20
20
|
@media (max-width:480px){.harkly-messenger[data-open]{inset:0;width:100%;height:100%;border-radius:0}}
|
|
21
|
-
@media (prefers-reduced-motion: reduce){.harkly-launcher,.harkly-messenger{transition:none}}`,
|
|
21
|
+
@media (prefers-reduced-motion: reduce){.harkly-launcher,.harkly-messenger{transition:none}}`,T='<svg class="harkly-ic-chat" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>',i='<svg class="harkly-ic-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M18 6 6 18M6 6l12 12"/></svg>';function D(e){if(!e||typeof e!=="object")return null;let y=e;if(y.type==="harkly:close")return{type:"harkly:close"};if(y.type==="harkly:unread"&&typeof y.count==="number")return{type:"harkly:unread",count:y.count};return null}function P(e,y,t,r){if(!e.getElementById(C)){let x=e.createElement("style");x.id=C,x.textContent=K,e.head.appendChild(x)}let k=t.position??"right",a=new URL(y).origin,l=e.createElement("iframe");l.className="harkly-messenger",l.dataset.side=k,l.title="Messages",l.setAttribute("allow","clipboard-write");let h=e.createElement("button");if(h.type="button",h.className="harkly-launcher",h.dataset.side=k,h.setAttribute("aria-label","Messages"),t.color)h.style.setProperty("--harkly-color",t.color);h.innerHTML=T+i;let f=e.createElement("span");f.className="harkly-badge",f.hidden=!0,h.appendChild(f);let b=!1,w=!1,m=(x)=>{if(w&&!x)return;let E={theme:t.theme,c:x};l.src=H(y,"messenger",E,r),w=!0},L=(x)=>{if(b=x,b)m(),l.dataset.open="",h.dataset.open="",l.focus();else delete l.dataset.open,delete h.dataset.open;h.setAttribute("aria-expanded",String(b))},U=(x)=>{if(x.origin!==a||x.source!==l.contentWindow)return;let E=D(x.data);if(E?.type==="harkly:close")L(!1);if(E?.type==="harkly:unread")f.hidden=E.count===0,f.textContent=String(E.count)},q=(x)=>{if(x.key==="Escape"&&b)L(!1)};if(h.addEventListener("click",()=>L(!b)),e.defaultView?.addEventListener("message",U),e.addEventListener("keydown",q),e.body.appendChild(l),t.launcher!==!1)e.body.appendChild(h);return m(),{open:(x)=>{if(x)m(x);L(!0)},close:()=>L(!1),toggle:()=>L(!b),destroy:()=>{e.defaultView?.removeEventListener("message",U),e.removeEventListener("keydown",q),l.remove(),h.remove()},get isOpen(){return b}}}var R="harkly-survey-style",G=`
|
|
22
|
+
.harkly-survey{position:fixed;bottom:20px;z-index:2147482999;width:min(380px,calc(100vw - 32px));height:260px;border:0;border-radius:14px;background:transparent;box-shadow:0 20px 48px rgba(0,0,0,.24);opacity:0;transform:translateY(12px);transition:opacity .2s ease,transform .24s cubic-bezier(.22,1,.36,1),height .2s ease}
|
|
23
|
+
.harkly-survey[data-side=right]{right:20px}.harkly-survey[data-side=left]{left:20px}
|
|
24
|
+
.harkly-survey[data-open]{opacity:1;transform:none}
|
|
25
|
+
@media (prefers-reduced-motion: reduce){.harkly-survey{transition:none}}`;function A(e){if(e.getElementById(R))return;let y=e.createElement("style");y.id=R,y.textContent=G,e.head.appendChild(y)}function n(e,y,t,r){A(e);let k=e.createElement("iframe");k.className="harkly-survey",k.dataset.side=r.side,k.src=y,k.title="Survey";let a=()=>{e.defaultView?.removeEventListener("message",l),k.removeAttribute("data-open"),setTimeout(()=>k.remove(),220)},l=(h)=>{if(h.origin!==t||h.source!==k.contentWindow)return;let f=W(h.data);if(!f)return;if(f.type==="harkly:height")k.style.height=`${Math.min(Math.max(f.height,120),640)}px`;if(f.type==="harkly:survey")if(r.onDone(f.status),f.status==="completed")setTimeout(a,2500);else a();if(f.type==="harkly:close")a()};return e.defaultView?.addEventListener("message",l),e.body.appendChild(k),e.defaultView?.requestAnimationFrame(()=>{k.dataset.open=""}),{close:a}}function $(e,y,t,r,k){let a=H(y,"survey",{slug:t.slug,theme:k.theme},r),l=new URL(y).origin,h=(f)=>{if(f==="completed")k.onComplete?.(t.slug);if(f==="dismissed")k.onDismiss?.(t.slug)};if(t.delivery.widget==="modal")return g(e,a,l,{onSurvey:h});return n(e,a,l,{side:k.position??"right",onDone:h})}function I(e,y){return y.delivery.widget!=="off"&&v(e,y.pages??void 0)}var z="harkly:anon";function S(){let e=new Uint8Array(16);return crypto.getRandomValues(e),Array.from(e,(y)=>y.toString(16).padStart(2,"0")).join("")}var Y={open:()=>{},close:()=>{},toggle:()=>{},destroy:()=>{},isOpen:!1};function _(){try{return typeof localStorage>"u"?void 0:localStorage}catch{return}}class F{publicKey;apiUrl;fetchImpl;storage;anonymousEnabled;currentUser;jwt;portal;messengerDefaults;configPromise;open;messengerHandle;surveyHandle;constructor(e){if(!e.publicKey?.startsWith("hk_pub_"))throw Error("Harkly: publicKey must be your hk_pub_… key");if(this.publicKey=e.publicKey,this.apiUrl=(e.apiUrl??"https://api.harkly.app").replace(/\/$/,""),this.fetchImpl=e.fetch??((y,t)=>fetch(y,t)),this.storage=e.storage??_(),this.anonymousEnabled=e.anonymous??!1,e.portalUrl)this.portal=Promise.resolve(e.portalUrl.replace(/\/$/,""))}anonymousId(){if(!this.anonymousEnabled||!this.storage)return;let e=this.storage.getItem(z)??void 0;if(!e)e=S(),this.storage.setItem(z,e);return e}get user(){return this.currentUser}async identify(e,y={}){if(!e?.id)throw Error("Harkly: identify needs a user id");let t={"content-type":"application/json","x-harkly-public-key":this.publicKey};if(y.jwt)t.authorization=`Bearer ${y.jwt}`;let r=await this.fetchImpl(`${this.apiUrl}/identify`,{method:"POST",headers:t,body:JSON.stringify({user:e,company:y.company,anonymousId:this.anonymousId()}),keepalive:!0});if(!r.ok){let k=await r.text().catch(()=>"");throw Error(`Harkly: identify failed (${r.status}) ${k}`.trim())}return this.currentUser=e,this.jwt=y.jwt,await r.json()}reset(){this.currentUser=void 0,this.jwt=void 0,this.storage?.removeItem(z),this.messengerHandle?.destroy(),this.messengerHandle=void 0}async messenger(e={}){this.messengerHandle?.destroy();let[y,t]=await Promise.all([this.portalUrl(),this.defaults()]);if(!v(document.location.pathname,t?.pages))return Y;return this.messengerHandle=P(document,y,O(e,t),{jwt:this.jwt,anonymousId:this.anonymousId()}),this.messengerHandle}config(){return this.configPromise??=this.fetchImpl(`${this.apiUrl}/portal/config`,{headers:{"x-harkly-public-key":this.publicKey}}).then((e)=>e.json()),this.configPromise}defaults(){return this.messengerDefaults??=this.config().then((e)=>({...e.org.messenger,color:e.org.messenger?.color??e.org.brandColor})).catch(()=>{return}),this.messengerDefaults}async portalUrl(){return this.portal??=this.config().then((e)=>`https://${e.org.slug}.harkly.app`),this.portal}async show(e,y,t,r){this.open?.close();let k=await this.portalUrl(),a=H(k,e,y,{jwt:this.jwt,anonymousId:this.anonymousId()});return this.open=g(document,a,new URL(k).origin,{side:t,onPosted:r,onClose:()=>{this.open=void 0}}),this.open}feedback(e={}){let{onPosted:y,...t}=e;return this.show("feedback",t,!1,y)}updates(e={}){return this.show("updates",e,!0)}identityHeaders(){let e={"x-harkly-public-key":this.publicKey};if(this.jwt)e.authorization=`Bearer ${this.jwt}`;let y=this.anonymousId();if(y)e["x-harkly-anonymous-id"]=y;return e}async unread(){let e=await this.fetchImpl(`${this.apiUrl}/portal/changelog/unread`,{headers:this.identityHeaders()});if(!e.ok)return 0;return(await e.json()).unread}async surveys(e={}){let y=await this.fetchImpl(`${this.apiUrl}/portal/surveys/eligible`,{headers:this.identityHeaders()}).catch(()=>{return});if(!y?.ok)return null;let{survey:t}=await y.json();if(!t||!I(document.location.pathname,t))return null;let r=await this.portalUrl(),k={jwt:this.jwt,anonymousId:this.anonymousId()};return await new Promise((a)=>setTimeout(a,(t.delivery.delaySeconds??0)*1000)),this.surveyHandle?.close(),this.surveyHandle=$(document,r,t,k,e),t.slug}async survey(e,y={}){let t=await this.portalUrl();return this.surveyHandle?.close(),this.surveyHandle=$(document,t,{id:"",slug:e,delivery:{widget:"modal"},pages:null},{jwt:this.jwt,anonymousId:this.anonymousId()},y),this.surveyHandle}}var V;function u(e){return V=new F(e),V}function j(){if(!V)throw Error("Harkly: call init({ publicKey }) first");return V}var d=(e,y)=>j().identify(e,y),c=()=>j().reset(),p=(e)=>j().feedback(e),s=(e)=>j().updates(e),o=()=>j().unread(),ee=(e)=>j().messenger(e),ye=(e)=>j().surveys(e),te=(e,y)=>j().survey(e,y);globalThis.Harkly=N;})();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { type FeedbackOptions, type OpenHandle, type UpdatesOptions } from "./widgets";
|
|
2
|
+
import { type SurveyOptions } from "./surveys";
|
|
2
3
|
import { type MessengerHandle, type MessengerOptions } from "./messenger";
|
|
3
4
|
export type { FeedbackOptions, UpdatesOptions, OpenHandle } from "./widgets";
|
|
4
5
|
export type { MessengerDefaults, MessengerHandle, MessengerOptions } from "./messenger";
|
|
6
|
+
export type { SurveyOptions } from "./surveys";
|
|
5
7
|
export type Attributes = Record<string, string | number | boolean | null>;
|
|
6
8
|
export interface HarklyUser {
|
|
7
9
|
id: string;
|
|
@@ -58,6 +60,7 @@ export declare class HarklyClient {
|
|
|
58
60
|
private configPromise?;
|
|
59
61
|
private open?;
|
|
60
62
|
private messengerHandle?;
|
|
63
|
+
private surveyHandle?;
|
|
61
64
|
constructor(options: InitOptions);
|
|
62
65
|
/** The anonymous id, created on first use when `anonymous` is on. */
|
|
63
66
|
anonymousId(): string | undefined;
|
|
@@ -67,7 +70,7 @@ export declare class HarklyClient {
|
|
|
67
70
|
reset(): void;
|
|
68
71
|
/**
|
|
69
72
|
* Put the messenger launcher on the page. Call again after identify to attach
|
|
70
|
-
* the user. Workspace settings (side,
|
|
73
|
+
* the user. Workspace settings (side, color, page rules) apply unless the
|
|
71
74
|
* option is given here; on a page the rules exclude, nothing mounts.
|
|
72
75
|
*/
|
|
73
76
|
messenger(options?: MessengerOptions): Promise<MessengerHandle>;
|
|
@@ -81,8 +84,17 @@ export declare class HarklyClient {
|
|
|
81
84
|
}): Promise<OpenHandle>;
|
|
82
85
|
/** Open the "what's new" panel. */
|
|
83
86
|
updates(options?: UpdatesOptions): Promise<OpenHandle>;
|
|
87
|
+
private identityHeaders;
|
|
84
88
|
/** Published updates the current user hasn't seen in the last 30 days. */
|
|
85
89
|
unread(): Promise<number>;
|
|
90
|
+
/**
|
|
91
|
+
* Ask the server whether a survey is due for this person and, if so, show
|
|
92
|
+
* it after its delay. Call once per page, after identify. Resolves to the
|
|
93
|
+
* survey's slug when one was shown.
|
|
94
|
+
*/
|
|
95
|
+
surveys(options?: SurveyOptions): Promise<string | null>;
|
|
96
|
+
/** Open one survey by slug as a modal, whatever its targeting says. */
|
|
97
|
+
survey(slug: string, options?: SurveyOptions): Promise<OpenHandle>;
|
|
86
98
|
}
|
|
87
99
|
export declare function init(options: InitOptions): HarklyClient;
|
|
88
100
|
export declare const identify: (user: HarklyUser, options?: IdentifyOptions) => Promise<IdentifyResult>;
|
|
@@ -91,3 +103,5 @@ export declare const feedback: (options?: Parameters<HarklyClient["feedback"]>[0
|
|
|
91
103
|
export declare const updates: (options?: UpdatesOptions) => Promise<OpenHandle>;
|
|
92
104
|
export declare const unread: () => Promise<number>;
|
|
93
105
|
export declare const messenger: (options?: MessengerOptions) => Promise<MessengerHandle>;
|
|
106
|
+
export declare const surveys: (options?: SurveyOptions) => Promise<string | null>;
|
|
107
|
+
export declare const survey: (slug: string, options?: SurveyOptions) => Promise<OpenHandle>;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
function
|
|
1
|
+
function v(e,y,t,r){let k=new URL(`/widget/${y}`,e);for(let[h,l]of Object.entries(t))if(l)k.searchParams.set(h,l);let f=new URLSearchParams;if(r.jwt)f.set("jwt",r.jwt);if(r.anonymousId)f.set("anon",r.anonymousId);let a=f.toString();return a?`${k.toString()}#${a}`:k.toString()}function g(e){if(!e||typeof e!=="object")return null;let y=e;if(y.type==="harkly:close")return{type:"harkly:close"};if(y.type==="harkly:posted"&&typeof y.postId==="string")return{type:"harkly:posted",postId:y.postId};if(y.type==="harkly:height"&&typeof y.height==="number")return{type:"harkly:height",height:y.height};if(y.type==="harkly:survey"&&(y.status==="completed"||y.status==="dismissed"||y.status==="none"))return{type:"harkly:survey",status:y.status};return null}var q="harkly-widget-style",I=`
|
|
2
2
|
.harkly-overlay{position:fixed;inset:0;z-index:2147483000;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:16px;opacity:0;transition:opacity .18s ease}
|
|
3
3
|
.harkly-overlay[data-open]{opacity:1}
|
|
4
4
|
.harkly-frame{border:0;width:min(560px,100%);height:min(640px,100%);border-radius:14px;background:transparent;box-shadow:0 24px 64px rgba(0,0,0,.35);transform:translateY(8px) scale(.98);transition:transform .22s cubic-bezier(.22,1,.36,1)}
|
|
@@ -6,7 +6,7 @@ function b(e,r,t,k){let y=new URL(`/widget/${r}`,e);for(let[a,f]of Object.entrie
|
|
|
6
6
|
.harkly-overlay[data-side] {justify-content:flex-end;padding:0}
|
|
7
7
|
.harkly-overlay[data-side] .harkly-frame{width:min(420px,100%);height:100%;border-radius:0;transform:translateX(24px)}
|
|
8
8
|
.harkly-overlay[data-side][data-open] .harkly-frame{transform:none}
|
|
9
|
-
@media (prefers-reduced-motion: reduce){.harkly-overlay,.harkly-frame{transition:none}}`;function
|
|
9
|
+
@media (prefers-reduced-motion: reduce){.harkly-overlay,.harkly-frame{transition:none}}`;function J(e){if(e.getElementById(q))return;let y=e.createElement("style");y.id=q,y.textContent=I,e.head.appendChild(y)}function V(e,y,t,r){J(e);let k=e.createElement("div");if(k.className="harkly-overlay",r.side)k.dataset.side="";let f=e.createElement("iframe");f.className="harkly-frame",f.src=y,f.title="Harkly",f.setAttribute("allow","clipboard-write"),k.appendChild(f);let a=e.activeElement,h=()=>{e.defaultView?.removeEventListener("message",l),e.removeEventListener("keydown",b),k.removeAttribute("data-open"),setTimeout(()=>k.remove(),200),a?.focus?.(),r.onClose?.()},l=(w)=>{if(w.origin!==t||w.source!==f.contentWindow)return;let m=g(w.data);if(!m)return;if(m.type==="harkly:close")h();if(m.type==="harkly:posted")r.onPosted?.(m.postId);if(m.type==="harkly:survey")if(r.onSurvey?.(m.status),m.status==="completed")setTimeout(h,2500);else h()},b=(w)=>{if(w.key==="Escape")h()};return k.addEventListener("click",(w)=>{if(w.target===k)h()}),e.defaultView?.addEventListener("message",l),e.addEventListener("keydown",b),e.body.appendChild(k),e.defaultView?.requestAnimationFrame(()=>{k.dataset.open="",f.focus()}),{close:h}}function Q(e){let y=e.replace(/[.+^${}()|[\]\\]/g,"\\$&").split("**").map((t)=>t.replace(/\*/g,"[^/]*")).join(".*");return new RegExp(`^${y}/?$`)}function W(e,y){if(!y||y.mode==="all"||y.patterns.length===0)return!0;let t=y.patterns.some((r)=>Q(r).test(e));return y.mode==="include"?t:!t}function C(e,y){if(!y)return e;return{position:e.position??y.position,color:e.color??y.color??void 0,launcher:e.launcher??y.launcher,theme:e.theme}}var B="harkly-messenger-style",X=`
|
|
10
10
|
.harkly-launcher{position:fixed;bottom:20px;z-index:2147483000;width:52px;height:52px;border:0;border-radius:50%;cursor:pointer;color:#fff;background:var(--harkly-color,#111);box-shadow:0 8px 24px rgba(0,0,0,.22);display:flex;align-items:center;justify-content:center;transition:transform .18s ease}
|
|
11
11
|
.harkly-launcher:hover{transform:scale(1.05)}
|
|
12
12
|
.harkly-launcher[data-side=right]{right:20px}.harkly-launcher[data-side=left]{left:20px}
|
|
@@ -18,7 +18,11 @@ function b(e,r,t,k){let y=new URL(`/widget/${r}`,e);for(let[a,f]of Object.entrie
|
|
|
18
18
|
.harkly-messenger[data-side=right]{right:20px}.harkly-messenger[data-side=left]{left:20px;transform-origin:bottom left}
|
|
19
19
|
.harkly-messenger[data-open]{opacity:1;pointer-events:auto;transform:none}
|
|
20
20
|
@media (max-width:480px){.harkly-messenger[data-open]{inset:0;width:100%;height:100%;border-radius:0}}
|
|
21
|
-
@media (prefers-reduced-motion: reduce){.harkly-launcher,.harkly-messenger{transition:none}}`,
|
|
21
|
+
@media (prefers-reduced-motion: reduce){.harkly-launcher,.harkly-messenger{transition:none}}`,Z='<svg class="harkly-ic-chat" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>',M='<svg class="harkly-ic-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M18 6 6 18M6 6l12 12"/></svg>';function G(e){if(!e||typeof e!=="object")return null;let y=e;if(y.type==="harkly:close")return{type:"harkly:close"};if(y.type==="harkly:unread"&&typeof y.count==="number")return{type:"harkly:unread",count:y.count};return null}function O(e,y,t,r){if(!e.getElementById(B)){let x=e.createElement("style");x.id=B,x.textContent=X,e.head.appendChild(x)}let k=t.position??"right",f=new URL(y).origin,a=e.createElement("iframe");a.className="harkly-messenger",a.dataset.side=k,a.title="Messages",a.setAttribute("allow","clipboard-write");let h=e.createElement("button");if(h.type="button",h.className="harkly-launcher",h.dataset.side=k,h.setAttribute("aria-label","Messages"),t.color)h.style.setProperty("--harkly-color",t.color);h.innerHTML=Z+M;let l=e.createElement("span");l.className="harkly-badge",l.hidden=!0,h.appendChild(l);let b=!1,w=!1,m=(x)=>{if(w&&!x)return;let E={theme:t.theme,c:x};a.src=v(y,"messenger",E,r),w=!0},L=(x)=>{if(b=x,b)m(),a.dataset.open="",h.dataset.open="",a.focus();else delete a.dataset.open,delete h.dataset.open;h.setAttribute("aria-expanded",String(b))},N=(x)=>{if(x.origin!==f||x.source!==a.contentWindow)return;let E=G(x.data);if(E?.type==="harkly:close")L(!1);if(E?.type==="harkly:unread")l.hidden=E.count===0,l.textContent=String(E.count)},U=(x)=>{if(x.key==="Escape"&&b)L(!1)};if(h.addEventListener("click",()=>L(!b)),e.defaultView?.addEventListener("message",N),e.addEventListener("keydown",U),e.body.appendChild(a),t.launcher!==!1)e.body.appendChild(h);return m(),{open:(x)=>{if(x)m(x);L(!0)},close:()=>L(!1),toggle:()=>L(!b),destroy:()=>{e.defaultView?.removeEventListener("message",N),e.removeEventListener("keydown",U),a.remove(),h.remove()},get isOpen(){return b}}}var P="harkly-survey-style",K=`
|
|
22
|
+
.harkly-survey{position:fixed;bottom:20px;z-index:2147482999;width:min(380px,calc(100vw - 32px));height:260px;border:0;border-radius:14px;background:transparent;box-shadow:0 20px 48px rgba(0,0,0,.24);opacity:0;transform:translateY(12px);transition:opacity .2s ease,transform .24s cubic-bezier(.22,1,.36,1),height .2s ease}
|
|
23
|
+
.harkly-survey[data-side=right]{right:20px}.harkly-survey[data-side=left]{left:20px}
|
|
24
|
+
.harkly-survey[data-open]{opacity:1;transform:none}
|
|
25
|
+
@media (prefers-reduced-motion: reduce){.harkly-survey{transition:none}}`;function T(e){if(e.getElementById(P))return;let y=e.createElement("style");y.id=P,y.textContent=K,e.head.appendChild(y)}function A(e,y,t,r){T(e);let k=e.createElement("iframe");k.className="harkly-survey",k.dataset.side=r.side,k.src=y,k.title="Survey";let f=()=>{e.defaultView?.removeEventListener("message",a),k.removeAttribute("data-open"),setTimeout(()=>k.remove(),220)},a=(h)=>{if(h.origin!==t||h.source!==k.contentWindow)return;let l=g(h.data);if(!l)return;if(l.type==="harkly:height")k.style.height=`${Math.min(Math.max(l.height,120),640)}px`;if(l.type==="harkly:survey")if(r.onDone(l.status),l.status==="completed")setTimeout(f,2500);else f();if(l.type==="harkly:close")f()};return e.defaultView?.addEventListener("message",a),e.body.appendChild(k),e.defaultView?.requestAnimationFrame(()=>{k.dataset.open=""}),{close:f}}function z(e,y,t,r,k){let f=v(y,"survey",{slug:t.slug,theme:k.theme},r),a=new URL(y).origin,h=(l)=>{if(l==="completed")k.onComplete?.(t.slug);if(l==="dismissed")k.onDismiss?.(t.slug)};if(t.delivery.widget==="modal")return V(e,f,a,{onSurvey:h});return A(e,f,a,{side:k.position??"right",onDone:h})}function R(e,y){return y.delivery.widget!=="off"&&W(e,y.pages??void 0)}var F="harkly:anon";function D(){let e=new Uint8Array(16);return crypto.getRandomValues(e),Array.from(e,(y)=>y.toString(16).padStart(2,"0")).join("")}var Y={open:()=>{},close:()=>{},toggle:()=>{},destroy:()=>{},isOpen:!1};function S(){try{return typeof localStorage>"u"?void 0:localStorage}catch{return}}class H{publicKey;apiUrl;fetchImpl;storage;anonymousEnabled;currentUser;jwt;portal;messengerDefaults;configPromise;open;messengerHandle;surveyHandle;constructor(e){if(!e.publicKey?.startsWith("hk_pub_"))throw Error("Harkly: publicKey must be your hk_pub_… key");if(this.publicKey=e.publicKey,this.apiUrl=(e.apiUrl??"https://api.harkly.app").replace(/\/$/,""),this.fetchImpl=e.fetch??((y,t)=>fetch(y,t)),this.storage=e.storage??S(),this.anonymousEnabled=e.anonymous??!1,e.portalUrl)this.portal=Promise.resolve(e.portalUrl.replace(/\/$/,""))}anonymousId(){if(!this.anonymousEnabled||!this.storage)return;let e=this.storage.getItem(F)??void 0;if(!e)e=D(),this.storage.setItem(F,e);return e}get user(){return this.currentUser}async identify(e,y={}){if(!e?.id)throw Error("Harkly: identify needs a user id");let t={"content-type":"application/json","x-harkly-public-key":this.publicKey};if(y.jwt)t.authorization=`Bearer ${y.jwt}`;let r=await this.fetchImpl(`${this.apiUrl}/identify`,{method:"POST",headers:t,body:JSON.stringify({user:e,company:y.company,anonymousId:this.anonymousId()}),keepalive:!0});if(!r.ok){let k=await r.text().catch(()=>"");throw Error(`Harkly: identify failed (${r.status}) ${k}`.trim())}return this.currentUser=e,this.jwt=y.jwt,await r.json()}reset(){this.currentUser=void 0,this.jwt=void 0,this.storage?.removeItem(F),this.messengerHandle?.destroy(),this.messengerHandle=void 0}async messenger(e={}){this.messengerHandle?.destroy();let[y,t]=await Promise.all([this.portalUrl(),this.defaults()]);if(!W(document.location.pathname,t?.pages))return Y;return this.messengerHandle=O(document,y,C(e,t),{jwt:this.jwt,anonymousId:this.anonymousId()}),this.messengerHandle}config(){return this.configPromise??=this.fetchImpl(`${this.apiUrl}/portal/config`,{headers:{"x-harkly-public-key":this.publicKey}}).then((e)=>e.json()),this.configPromise}defaults(){return this.messengerDefaults??=this.config().then((e)=>({...e.org.messenger,color:e.org.messenger?.color??e.org.brandColor})).catch(()=>{return}),this.messengerDefaults}async portalUrl(){return this.portal??=this.config().then((e)=>`https://${e.org.slug}.harkly.app`),this.portal}async show(e,y,t,r){this.open?.close();let k=await this.portalUrl(),f=v(k,e,y,{jwt:this.jwt,anonymousId:this.anonymousId()});return this.open=V(document,f,new URL(k).origin,{side:t,onPosted:r,onClose:()=>{this.open=void 0}}),this.open}feedback(e={}){let{onPosted:y,...t}=e;return this.show("feedback",t,!1,y)}updates(e={}){return this.show("updates",e,!0)}identityHeaders(){let e={"x-harkly-public-key":this.publicKey};if(this.jwt)e.authorization=`Bearer ${this.jwt}`;let y=this.anonymousId();if(y)e["x-harkly-anonymous-id"]=y;return e}async unread(){let e=await this.fetchImpl(`${this.apiUrl}/portal/changelog/unread`,{headers:this.identityHeaders()});if(!e.ok)return 0;return(await e.json()).unread}async surveys(e={}){let y=await this.fetchImpl(`${this.apiUrl}/portal/surveys/eligible`,{headers:this.identityHeaders()}).catch(()=>{return});if(!y?.ok)return null;let{survey:t}=await y.json();if(!t||!R(document.location.pathname,t))return null;let r=await this.portalUrl(),k={jwt:this.jwt,anonymousId:this.anonymousId()};return await new Promise((f)=>setTimeout(f,(t.delivery.delaySeconds??0)*1000)),this.surveyHandle?.close(),this.surveyHandle=z(document,r,t,k,e),t.slug}async survey(e,y={}){let t=await this.portalUrl();return this.surveyHandle?.close(),this.surveyHandle=z(document,t,{id:"",slug:e,delivery:{widget:"modal"},pages:null},{jwt:this.jwt,anonymousId:this.anonymousId()},y),this.surveyHandle}}var $;function ee(e){return $=new H(e),$}function j(){if(!$)throw Error("Harkly: call init({ publicKey }) first");return $}var ye=(e,y)=>j().identify(e,y),te=()=>j().reset(),ke=(e)=>j().feedback(e),he=(e)=>j().updates(e),re=()=>j().unread(),fe=(e)=>j().messenger(e),ae=(e)=>j().surveys(e),le=(e,y)=>j().survey(e,y);export{he as updates,re as unread,ae as surveys,le as survey,te as reset,fe as messenger,ee as init,ye as identify,ke as feedback,H as HarklyClient};
|
|
22
26
|
|
|
23
|
-
//# debugId=
|
|
27
|
+
//# debugId=0CC6414E5AA1971964756E2164756E21
|
|
24
28
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/widgets.ts", "../src/messenger.ts", "../src/index.ts"],
|
|
3
|
+
"sources": ["../src/widgets.ts", "../src/messenger.ts", "../src/surveys.ts", "../src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"// The feedback modal and the updates panel are the hosted portal in an\n// iframe. The page never sees the customer's session; identity travels in\n// the URL fragment, which browsers keep out of referrers and server logs.\nexport type WidgetIdentity = { jwt?: string; anonymousId?: string };\nexport type FeedbackOptions = { board?: string; title?: string; theme?: \"light\" | \"dark\" | \"system\" };\nexport type UpdatesOptions = { theme?: \"light\" | \"dark\" | \"system\" };\n\nexport function widgetUrl(portalUrl: string, kind: \"feedback\" | \"updates\" | \"messenger\", options: Record<string, string | undefined>, identity: WidgetIdentity): string {\n const url = new URL(`/widget/${kind}`, portalUrl);\n for (const [k, v] of Object.entries(options)) if (v) url.searchParams.set(k, v);\n const frag = new URLSearchParams();\n if (identity.jwt) frag.set(\"jwt\", identity.jwt);\n if (identity.anonymousId) frag.set(\"anon\", identity.anonymousId);\n const f = frag.toString();\n return f ? `${url.toString()}#${f}` : url.toString();\n}\n\ntype Message = { type: \"harkly:close\" } | { type: \"harkly:posted\"; postId: string } | { type: \"harkly:height\"; height: number };\n\nexport function parseMessage(data: unknown): Message | null {\n if (!data || typeof data !== \"object\") return null;\n const m = data as Record<string, unknown>;\n if (m.type === \"harkly:close\") return { type: \"harkly:close\" };\n if (m.type === \"harkly:posted\" && typeof m.postId === \"string\") return { type: \"harkly:posted\", postId: m.postId };\n if (m.type === \"harkly:height\" && typeof m.height === \"number\") return { type: \"harkly:height\", height: m.height };\n return null;\n}\n\nconst STYLE_ID = \"harkly-widget-style\";\nconst CSS = `\n.harkly-overlay{position:fixed;inset:0;z-index:2147483000;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:16px;opacity:0;transition:opacity .18s ease}\n.harkly-overlay[data-open]{opacity:1}\n.harkly-frame{border:0;width:min(560px,100%);height:min(640px,100%);border-radius:14px;background:transparent;box-shadow:0 24px 64px rgba(0,0,0,.35);transform:translateY(8px) scale(.98);transition:transform .22s cubic-bezier(.22,1,.36,1)}\n.harkly-overlay[data-open] .harkly-frame{transform:none}\n.harkly-overlay[data-side] {justify-content:flex-end;padding:0}\n.harkly-overlay[data-side] .harkly-frame{width:min(420px,100%);height:100%;border-radius:0;transform:translateX(24px)}\n.harkly-overlay[data-side][data-open] .harkly-frame{transform:none}\n@media (prefers-reduced-motion: reduce){.harkly-overlay,.harkly-frame{transition:none}}`;\n\nfunction ensureStyle(doc: Document): void {\n if (doc.getElementById(STYLE_ID)) return;\n const style = doc.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = CSS;\n doc.head.appendChild(style);\n}\n\nexport type OpenHandle = { close: () => void };\n\nexport function openFrame(doc: Document, src: string, origin: string, opts: { side?: boolean; onPosted?: (postId: string) => void; onClose?: () => void }): OpenHandle {\n ensureStyle(doc);\n const overlay = doc.createElement(\"div\");\n overlay.className = \"harkly-overlay\";\n if (opts.side) overlay.dataset.side = \"\";\n const frame = doc.createElement(\"iframe\");\n frame.className = \"harkly-frame\";\n frame.src = src;\n frame.title = \"Harkly\";\n frame.setAttribute(\"allow\", \"clipboard-write\");\n overlay.appendChild(frame);\n const previousFocus = doc.activeElement as HTMLElement | null;\n const close = () => {\n doc.defaultView?.removeEventListener(\"message\", onMessage);\n doc.removeEventListener(\"keydown\", onKey);\n overlay.removeAttribute(\"data-open\");\n setTimeout(() => overlay.remove(), 200);\n previousFocus?.focus?.();\n opts.onClose?.();\n };\n const onMessage = (e: MessageEvent) => {\n if (e.origin !== origin || e.source !== frame.contentWindow) return;\n const m = parseMessage(e.data);\n if (!m) return;\n if (m.type === \"harkly:close\") close();\n if (m.type === \"harkly:posted\") opts.onPosted?.(m.postId);\n };\n const onKey = (e: KeyboardEvent) => { if (e.key === \"Escape\") close(); };\n overlay.addEventListener(\"click\", (e) => { if (e.target === overlay) close(); });\n doc.defaultView?.addEventListener(\"message\", onMessage);\n doc.addEventListener(\"keydown\", onKey);\n doc.body.appendChild(overlay);\n requestAnimationFrame(() => { overlay.dataset.open = \"\"; frame.focus(); });\n return { close };\n}\n",
|
|
5
|
+
"// The feedback modal and the updates panel are the hosted portal in an\n// iframe. The page never sees the customer's session; identity travels in\n// the URL fragment, which browsers keep out of referrers and server logs.\nexport type WidgetIdentity = { jwt?: string; anonymousId?: string };\nexport type FeedbackOptions = { board?: string; title?: string; theme?: \"light\" | \"dark\" | \"system\" };\nexport type UpdatesOptions = { theme?: \"light\" | \"dark\" | \"system\" };\n\nexport function widgetUrl(portalUrl: string, kind: \"feedback\" | \"updates\" | \"messenger\" | \"survey\", options: Record<string, string | undefined>, identity: WidgetIdentity): string {\n const url = new URL(`/widget/${kind}`, portalUrl);\n for (const [k, v] of Object.entries(options)) if (v) url.searchParams.set(k, v);\n const frag = new URLSearchParams();\n if (identity.jwt) frag.set(\"jwt\", identity.jwt);\n if (identity.anonymousId) frag.set(\"anon\", identity.anonymousId);\n const f = frag.toString();\n return f ? `${url.toString()}#${f}` : url.toString();\n}\n\ntype Message = { type: \"harkly:close\" } | { type: \"harkly:posted\"; postId: string } | { type: \"harkly:height\"; height: number } | { type: \"harkly:survey\"; status: \"completed\" | \"dismissed\" | \"none\" };\n\nexport function parseMessage(data: unknown): Message | null {\n if (!data || typeof data !== \"object\") return null;\n const m = data as Record<string, unknown>;\n if (m.type === \"harkly:close\") return { type: \"harkly:close\" };\n if (m.type === \"harkly:posted\" && typeof m.postId === \"string\") return { type: \"harkly:posted\", postId: m.postId };\n if (m.type === \"harkly:height\" && typeof m.height === \"number\") return { type: \"harkly:height\", height: m.height };\n if (m.type === \"harkly:survey\" && (m.status === \"completed\" || m.status === \"dismissed\" || m.status === \"none\")) return { type: \"harkly:survey\", status: m.status };\n return null;\n}\n\nconst STYLE_ID = \"harkly-widget-style\";\nconst CSS = `\n.harkly-overlay{position:fixed;inset:0;z-index:2147483000;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:16px;opacity:0;transition:opacity .18s ease}\n.harkly-overlay[data-open]{opacity:1}\n.harkly-frame{border:0;width:min(560px,100%);height:min(640px,100%);border-radius:14px;background:transparent;box-shadow:0 24px 64px rgba(0,0,0,.35);transform:translateY(8px) scale(.98);transition:transform .22s cubic-bezier(.22,1,.36,1)}\n.harkly-overlay[data-open] .harkly-frame{transform:none}\n.harkly-overlay[data-side] {justify-content:flex-end;padding:0}\n.harkly-overlay[data-side] .harkly-frame{width:min(420px,100%);height:100%;border-radius:0;transform:translateX(24px)}\n.harkly-overlay[data-side][data-open] .harkly-frame{transform:none}\n@media (prefers-reduced-motion: reduce){.harkly-overlay,.harkly-frame{transition:none}}`;\n\nfunction ensureStyle(doc: Document): void {\n if (doc.getElementById(STYLE_ID)) return;\n const style = doc.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = CSS;\n doc.head.appendChild(style);\n}\n\nexport type OpenHandle = { close: () => void };\n\nexport function openFrame(doc: Document, src: string, origin: string, opts: { side?: boolean; onPosted?: (postId: string) => void; onSurvey?: (status: \"completed\" | \"dismissed\" | \"none\") => void; onClose?: () => void }): OpenHandle {\n ensureStyle(doc);\n const overlay = doc.createElement(\"div\");\n overlay.className = \"harkly-overlay\";\n if (opts.side) overlay.dataset.side = \"\";\n const frame = doc.createElement(\"iframe\");\n frame.className = \"harkly-frame\";\n frame.src = src;\n frame.title = \"Harkly\";\n frame.setAttribute(\"allow\", \"clipboard-write\");\n overlay.appendChild(frame);\n const previousFocus = doc.activeElement as HTMLElement | null;\n const close = () => {\n doc.defaultView?.removeEventListener(\"message\", onMessage);\n doc.removeEventListener(\"keydown\", onKey);\n overlay.removeAttribute(\"data-open\");\n setTimeout(() => overlay.remove(), 200);\n previousFocus?.focus?.();\n opts.onClose?.();\n };\n const onMessage = (e: MessageEvent) => {\n if (e.origin !== origin || e.source !== frame.contentWindow) return;\n const m = parseMessage(e.data);\n if (!m) return;\n if (m.type === \"harkly:close\") close();\n if (m.type === \"harkly:posted\") opts.onPosted?.(m.postId);\n if (m.type === \"harkly:survey\") {\n opts.onSurvey?.(m.status);\n if (m.status === \"completed\") setTimeout(close, 2500);\n else close();\n }\n };\n const onKey = (e: KeyboardEvent) => { if (e.key === \"Escape\") close(); };\n overlay.addEventListener(\"click\", (e) => { if (e.target === overlay) close(); });\n doc.defaultView?.addEventListener(\"message\", onMessage);\n doc.addEventListener(\"keydown\", onKey);\n doc.body.appendChild(overlay);\n doc.defaultView?.requestAnimationFrame(() => { overlay.dataset.open = \"\"; frame.focus(); });\n return { close };\n}\n",
|
|
6
6
|
"// The messenger: a launcher in the corner and the hosted conversation UI in\n// an iframe that stays mounted once opened, so the live connection inside\n// it keeps the unread badge honest while it's hidden.\nimport { widgetUrl, type WidgetIdentity } from \"./widgets\";\n\nexport type MessengerOptions = { position?: \"right\" | \"left\"; launcher?: boolean; theme?: \"light\" | \"dark\" | \"system\"; color?: string };\n/** What the workspace configured in Settings; explicit options win over it. */\nexport type MessengerDefaults = { position?: \"right\" | \"left\"; color?: string | null; launcher?: boolean; pages?: { mode: \"all\" | \"include\" | \"exclude\"; patterns: string[] } };\n\n// Page rules are globs over the path: `/app/*` matches one segment, `/docs/**` any depth.\nfunction globToRegExp(pattern: string): RegExp {\n const escaped = pattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\").split(\"**\").map((part) => part.replace(/\\*/g, \"[^/]*\")).join(\".*\");\n return new RegExp(`^${escaped}/?$`);\n}\nexport function pageAllowed(pathname: string, pages: MessengerDefaults[\"pages\"] | undefined): boolean {\n if (!pages || pages.mode === \"all\" || pages.patterns.length === 0) return true;\n const hit = pages.patterns.some((p) => globToRegExp(p).test(pathname));\n return pages.mode === \"include\" ? hit : !hit;\n}\nexport function withDefaults(options: MessengerOptions, defaults: MessengerDefaults | undefined): MessengerOptions {\n if (!defaults) return options;\n return { position: options.position ?? defaults.position, color: options.color ?? defaults.color ?? undefined, launcher: options.launcher ?? defaults.launcher, theme: options.theme };\n}\nexport type MessengerHandle = { open: (conversationId?: string) => void; close: () => void; toggle: () => void; destroy: () => void; readonly isOpen: boolean };\n\nconst STYLE_ID = \"harkly-messenger-style\";\nconst CSS = `\n.harkly-launcher{position:fixed;bottom:20px;z-index:2147483000;width:52px;height:52px;border:0;border-radius:50%;cursor:pointer;color:#fff;background:var(--harkly-color,#111);box-shadow:0 8px 24px rgba(0,0,0,.22);display:flex;align-items:center;justify-content:center;transition:transform .18s ease}\n.harkly-launcher:hover{transform:scale(1.05)}\n.harkly-launcher[data-side=right]{right:20px}.harkly-launcher[data-side=left]{left:20px}\n.harkly-launcher svg{width:24px;height:24px;transition:opacity .15s,transform .2s}\n.harkly-launcher[data-open] .harkly-ic-chat{opacity:0;transform:scale(.6)}.harkly-launcher:not([data-open]) .harkly-ic-x{opacity:0;transform:scale(.6)}\n.harkly-launcher .harkly-ic-x{position:absolute}\n.harkly-badge{position:absolute;top:-2px;right:-2px;min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:#e5484d;color:#fff;font:600 11px/18px system-ui,sans-serif;text-align:center}\n.harkly-messenger{position:fixed;bottom:84px;z-index:2147483000;width:min(400px,calc(100vw - 32px));height:min(704px,calc(100vh - 104px));border:0;border-radius:16px;background:transparent;box-shadow:0 24px 64px rgba(0,0,0,.28);opacity:0;pointer-events:none;transform:translateY(12px) scale(.98);transform-origin:bottom right;transition:opacity .18s ease,transform .22s cubic-bezier(.22,1,.36,1)}\n.harkly-messenger[data-side=right]{right:20px}.harkly-messenger[data-side=left]{left:20px;transform-origin:bottom left}\n.harkly-messenger[data-open]{opacity:1;pointer-events:auto;transform:none}\n@media (max-width:480px){.harkly-messenger[data-open]{inset:0;width:100%;height:100%;border-radius:0}}\n@media (prefers-reduced-motion: reduce){.harkly-launcher,.harkly-messenger{transition:none}}`;\n\nconst CHAT = '<svg class=\"harkly-ic-chat\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\"/></svg>';\nconst X = '<svg class=\"harkly-ic-x\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><path d=\"M18 6 6 18M6 6l12 12\"/></svg>';\n\ntype Message = { type: \"harkly:close\" } | { type: \"harkly:unread\"; count: number };\nfunction parse(data: unknown): Message | null {\n if (!data || typeof data !== \"object\") return null;\n const m = data as Record<string, unknown>;\n if (m.type === \"harkly:close\") return { type: \"harkly:close\" };\n if (m.type === \"harkly:unread\" && typeof m.count === \"number\") return { type: \"harkly:unread\", count: m.count };\n return null;\n}\n\nexport function mountMessenger(doc: Document, portal: string, options: MessengerOptions, identity: WidgetIdentity): MessengerHandle {\n if (!doc.getElementById(STYLE_ID)) {\n const style = doc.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = CSS;\n doc.head.appendChild(style);\n }\n const side = options.position ?? \"right\";\n const origin = new URL(portal).origin;\n const frame = doc.createElement(\"iframe\");\n frame.className = \"harkly-messenger\";\n frame.dataset.side = side;\n frame.title = \"Messages\";\n frame.setAttribute(\"allow\", \"clipboard-write\");\n const launcher = doc.createElement(\"button\");\n launcher.type = \"button\";\n launcher.className = \"harkly-launcher\";\n launcher.dataset.side = side;\n launcher.setAttribute(\"aria-label\", \"Messages\");\n if (options.color) launcher.style.setProperty(\"--harkly-color\", options.color);\n launcher.innerHTML = CHAT + X;\n const badge = doc.createElement(\"span\");\n badge.className = \"harkly-badge\";\n badge.hidden = true;\n launcher.appendChild(badge);\n let open = false;\n let loaded = false;\n const load = (conversationId?: string) => {\n if (loaded && !conversationId) return;\n const opts: Record<string, string | undefined> = { theme: options.theme, c: conversationId };\n frame.src = widgetUrl(portal, \"messenger\", opts, identity);\n loaded = true;\n };\n const set = (next: boolean) => {\n open = next;\n if (open) { load(); frame.dataset.open = \"\"; launcher.dataset.open = \"\"; frame.focus(); }\n else { delete frame.dataset.open; delete launcher.dataset.open; }\n launcher.setAttribute(\"aria-expanded\", String(open));\n };\n const onMessage = (e: MessageEvent) => {\n if (e.origin !== origin || e.source !== frame.contentWindow) return;\n const m = parse(e.data);\n if (m?.type === \"harkly:close\") set(false);\n if (m?.type === \"harkly:unread\") {\n badge.hidden = m.count === 0;\n badge.textContent = String(m.count);\n }\n };\n const onKey = (e: KeyboardEvent) => { if (e.key === \"Escape\" && open) set(false); };\n launcher.addEventListener(\"click\", () => set(!open));\n doc.defaultView?.addEventListener(\"message\", onMessage);\n doc.addEventListener(\"keydown\", onKey);\n doc.body.appendChild(frame);\n if (options.launcher !== false) doc.body.appendChild(launcher);\n // the frame loads right away so unread counts arrive before the first click\n load();\n return {\n open: (conversationId) => {\n if (conversationId) load(conversationId);\n set(true);\n },\n close: () => set(false),\n toggle: () => set(!open),\n destroy: () => {\n doc.defaultView?.removeEventListener(\"message\", onMessage);\n doc.removeEventListener(\"keydown\", onKey);\n frame.remove();\n launcher.remove();\n },\n get isOpen() { return open; },\n };\n}\n",
|
|
7
|
-
"//
|
|
7
|
+
"// A survey the server says this person may see, shown as a small card in\n// the corner or a modal. The server picked it and will refuse a second look;\n// the SDK only decides when and where on the page.\nimport { openFrame, parseMessage, widgetUrl, type OpenHandle, type WidgetIdentity } from \"./widgets\";\nimport { pageAllowed, type MessengerDefaults } from \"./messenger\";\n\nexport type EligibleSurvey = { id: string; slug: string; delivery: { widget: \"card\" | \"modal\" | \"off\"; delaySeconds?: number }; pages: MessengerDefaults[\"pages\"] | null };\nexport type SurveyOptions = { position?: \"right\" | \"left\"; theme?: \"light\" | \"dark\" | \"system\"; onComplete?: (slug: string) => void; onDismiss?: (slug: string) => void };\n\nconst STYLE_ID = \"harkly-survey-style\";\nconst CSS = `\n.harkly-survey{position:fixed;bottom:20px;z-index:2147482999;width:min(380px,calc(100vw - 32px));height:260px;border:0;border-radius:14px;background:transparent;box-shadow:0 20px 48px rgba(0,0,0,.24);opacity:0;transform:translateY(12px);transition:opacity .2s ease,transform .24s cubic-bezier(.22,1,.36,1),height .2s ease}\n.harkly-survey[data-side=right]{right:20px}.harkly-survey[data-side=left]{left:20px}\n.harkly-survey[data-open]{opacity:1;transform:none}\n@media (prefers-reduced-motion: reduce){.harkly-survey{transition:none}}`;\n\nfunction ensureStyle(doc: Document): void {\n if (doc.getElementById(STYLE_ID)) return;\n const style = doc.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = CSS;\n doc.head.appendChild(style);\n}\n\ntype CardOpts = { side: \"right\" | \"left\"; onDone: (status: \"completed\" | \"dismissed\" | \"none\") => void };\n\nfunction mountSurveyCard(doc: Document, src: string, origin: string, opts: CardOpts): OpenHandle {\n ensureStyle(doc);\n const frame = doc.createElement(\"iframe\");\n frame.className = \"harkly-survey\";\n frame.dataset.side = opts.side;\n frame.src = src;\n frame.title = \"Survey\";\n const close = () => {\n doc.defaultView?.removeEventListener(\"message\", onMessage);\n frame.removeAttribute(\"data-open\");\n setTimeout(() => frame.remove(), 220);\n };\n const onMessage = (e: MessageEvent) => {\n if (e.origin !== origin || e.source !== frame.contentWindow) return;\n const m = parseMessage(e.data);\n if (!m) return;\n if (m.type === \"harkly:height\") frame.style.height = `${Math.min(Math.max(m.height, 120), 640)}px`;\n if (m.type === \"harkly:survey\") {\n opts.onDone(m.status);\n // a finished survey lingers on its thank-you for a moment\n if (m.status === \"completed\") setTimeout(close, 2500);\n else close();\n }\n if (m.type === \"harkly:close\") close();\n };\n doc.defaultView?.addEventListener(\"message\", onMessage);\n doc.body.appendChild(frame);\n doc.defaultView?.requestAnimationFrame(() => { frame.dataset.open = \"\"; });\n return { close };\n}\n\nexport function showSurvey(doc: Document, portal: string, survey: EligibleSurvey, identity: WidgetIdentity, options: SurveyOptions): OpenHandle {\n const src = widgetUrl(portal, \"survey\", { slug: survey.slug, theme: options.theme }, identity);\n const origin = new URL(portal).origin;\n const onDone = (status: \"completed\" | \"dismissed\" | \"none\") => {\n if (status === \"completed\") options.onComplete?.(survey.slug);\n if (status === \"dismissed\") options.onDismiss?.(survey.slug);\n };\n if (survey.delivery.widget === \"modal\") return openFrame(doc, src, origin, { onSurvey: onDone });\n return mountSurveyCard(doc, src, origin, { side: options.position ?? \"right\", onDone });\n}\n\nexport function surveyAllowedHere(pathname: string, survey: EligibleSurvey): boolean {\n return survey.delivery.widget !== \"off\" && pageAllowed(pathname, survey.pages ?? undefined);\n}\n",
|
|
8
|
+
"// Harkly browser SDK: tell Harkly who the current user is, open the feedback\n// modal, show what's new.\nimport { openFrame, widgetUrl, type FeedbackOptions, type OpenHandle, type UpdatesOptions } from \"./widgets\";\nimport { showSurvey, surveyAllowedHere, type EligibleSurvey, type SurveyOptions } from \"./surveys\";\nimport { mountMessenger, pageAllowed, withDefaults, type MessengerDefaults, type MessengerHandle, type MessengerOptions } from \"./messenger\";\nexport type { FeedbackOptions, UpdatesOptions, OpenHandle } from \"./widgets\";\nexport type { MessengerDefaults, MessengerHandle, MessengerOptions } from \"./messenger\";\nexport type { SurveyOptions } from \"./surveys\";\n\nexport type Attributes = Record<string, string | number | boolean | null>;\n\nexport interface HarklyUser {\n id: string;\n email?: string;\n name?: string;\n avatarUrl?: string;\n plan?: string;\n mrr?: number;\n createdAt?: string;\n custom?: Attributes;\n}\n\nexport interface HarklyCompany {\n id: string;\n name?: string;\n domain?: string;\n plan?: string;\n mrr?: number;\n custom?: Attributes;\n}\n\nexport interface InitOptions {\n /** Your org's public key from Settings → SDK. Safe to ship in the browser. */\n publicKey: string;\n /** Defaults to https://api.harkly.app. */\n apiUrl?: string;\n /** Your portal, e.g. https://acme.harkly.app. Looked up from the public key when omitted. */\n portalUrl?: string;\n /** Keep an anonymous id in storage before identify so later votes can be attributed. Off by default: no cookie until you say so. */\n anonymous?: boolean;\n /** Override fetch (tests, SSR). */\n fetch?: typeof fetch;\n /** Override storage (tests, SSR). */\n storage?: Pick<Storage, \"getItem\" | \"setItem\" | \"removeItem\">;\n}\n\nexport interface IdentifyOptions {\n /** A JWT signed with your SSO secret, `sub` = user id. Lets Harkly trust email changes. */\n jwt?: string;\n company?: HarklyCompany;\n}\n\nexport interface IdentifyResult { userId: string; companyId: string | null; created: boolean }\n\nconst STORAGE_KEY = \"harkly:anon\";\n\nfunction randomId(): string {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n return Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\ntype PortalConfig = { org: { slug: string; brandColor?: string | null; messenger?: MessengerDefaults } };\n// what messenger() hands back on a page the workspace's rules keep it off\nconst idleMessenger: MessengerHandle = { open: () => {}, close: () => {}, toggle: () => {}, destroy: () => {}, isOpen: false };\n\nfunction defaultStorage(): InitOptions[\"storage\"] | undefined {\n try {\n return typeof localStorage === \"undefined\" ? undefined : localStorage;\n } catch {\n return undefined;\n }\n}\n\nexport class HarklyClient {\n private readonly publicKey: string;\n private readonly apiUrl: string;\n private readonly fetchImpl: typeof fetch;\n private readonly storage?: InitOptions[\"storage\"];\n private readonly anonymousEnabled: boolean;\n private currentUser?: HarklyUser;\n private jwt?: string;\n private portal?: Promise<string>;\n private messengerDefaults?: Promise<MessengerDefaults | undefined>;\n private configPromise?: Promise<PortalConfig>;\n private open?: OpenHandle;\n private messengerHandle?: MessengerHandle;\n private surveyHandle?: OpenHandle;\n\n constructor(options: InitOptions) {\n if (!options.publicKey?.startsWith(\"hk_pub_\")) throw new Error(\"Harkly: publicKey must be your hk_pub_… key\");\n this.publicKey = options.publicKey;\n this.apiUrl = (options.apiUrl ?? \"https://api.harkly.app\").replace(/\\/$/, \"\");\n // bound, or the browser throws \"Illegal invocation\" when it's called off `this`\n this.fetchImpl = options.fetch ?? ((input: RequestInfo | URL, init?: RequestInit) => fetch(input, init)) as typeof fetch;\n this.storage = options.storage ?? defaultStorage();\n this.anonymousEnabled = options.anonymous ?? false;\n if (options.portalUrl) this.portal = Promise.resolve(options.portalUrl.replace(/\\/$/, \"\"));\n }\n\n /** The anonymous id, created on first use when `anonymous` is on. */\n anonymousId(): string | undefined {\n if (!this.anonymousEnabled || !this.storage) return undefined;\n let id = this.storage.getItem(STORAGE_KEY) ?? undefined;\n if (!id) {\n id = randomId();\n this.storage.setItem(STORAGE_KEY, id);\n }\n return id;\n }\n\n get user(): HarklyUser | undefined {\n return this.currentUser;\n }\n\n async identify(user: HarklyUser, options: IdentifyOptions = {}): Promise<IdentifyResult> {\n if (!user?.id) throw new Error(\"Harkly: identify needs a user id\");\n const headers: Record<string, string> = { \"content-type\": \"application/json\", \"x-harkly-public-key\": this.publicKey };\n if (options.jwt) headers.authorization = `Bearer ${options.jwt}`;\n const response = await this.fetchImpl(`${this.apiUrl}/identify`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ user, company: options.company, anonymousId: this.anonymousId() }),\n keepalive: true,\n });\n if (!response.ok) {\n const detail = await response.text().catch(() => \"\");\n throw new Error(`Harkly: identify failed (${response.status}) ${detail}`.trim());\n }\n this.currentUser = user;\n this.jwt = options.jwt;\n return (await response.json()) as IdentifyResult;\n }\n\n /** Forget the current user and the anonymous id, e.g. on sign-out. */\n reset(): void {\n this.currentUser = undefined;\n this.jwt = undefined;\n this.storage?.removeItem(STORAGE_KEY);\n this.messengerHandle?.destroy();\n this.messengerHandle = undefined;\n }\n\n /**\n * Put the messenger launcher on the page. Call again after identify to attach\n * the user. Workspace settings (side, color, page rules) apply unless the\n * option is given here; on a page the rules exclude, nothing mounts.\n */\n async messenger(options: MessengerOptions = {}): Promise<MessengerHandle> {\n this.messengerHandle?.destroy();\n const [portal, defaults] = await Promise.all([this.portalUrl(), this.defaults()]);\n if (!pageAllowed(document.location.pathname, defaults?.pages)) return idleMessenger;\n this.messengerHandle = mountMessenger(document, portal, withDefaults(options, defaults), { jwt: this.jwt, anonymousId: this.anonymousId() });\n return this.messengerHandle;\n }\n\n private config(): Promise<PortalConfig> {\n this.configPromise ??= this.fetchImpl(`${this.apiUrl}/portal/config`, { headers: { \"x-harkly-public-key\": this.publicKey } }).then((r) => r.json() as Promise<PortalConfig>);\n return this.configPromise;\n }\n private defaults(): Promise<MessengerDefaults | undefined> {\n // the launcher wears the brand color unless the messenger settings say otherwise\n this.messengerDefaults ??= this.config().then((c) => ({ ...c.org.messenger, color: c.org.messenger?.color ?? c.org.brandColor })).catch(() => undefined);\n return this.messengerDefaults;\n }\n\n private async portalUrl(): Promise<string> {\n this.portal ??= this.config().then((c) => `https://${c.org.slug}.harkly.app`);\n return this.portal;\n }\n\n private async show(kind: \"feedback\" | \"updates\", options: Record<string, string | undefined>, side: boolean, onPosted?: (postId: string) => void): Promise<OpenHandle> {\n this.open?.close();\n const portal = await this.portalUrl();\n const src = widgetUrl(portal, kind, options, { jwt: this.jwt, anonymousId: this.anonymousId() });\n this.open = openFrame(document, src, new URL(portal).origin, { side, onPosted, onClose: () => { this.open = undefined; } });\n return this.open;\n }\n\n /** Open the feedback modal. Resolves once it's on screen. */\n feedback(options: FeedbackOptions & { onPosted?: (postId: string) => void } = {}): Promise<OpenHandle> {\n const { onPosted, ...rest } = options;\n return this.show(\"feedback\", rest, false, onPosted);\n }\n\n /** Open the \"what's new\" panel. */\n updates(options: UpdatesOptions = {}): Promise<OpenHandle> {\n return this.show(\"updates\", options, true);\n }\n\n private identityHeaders(): Record<string, string> {\n const headers: Record<string, string> = { \"x-harkly-public-key\": this.publicKey };\n if (this.jwt) headers.authorization = `Bearer ${this.jwt}`;\n const anon = this.anonymousId();\n if (anon) headers[\"x-harkly-anonymous-id\"] = anon;\n return headers;\n }\n\n /** Published updates the current user hasn't seen in the last 30 days. */\n async unread(): Promise<number> {\n const r = await this.fetchImpl(`${this.apiUrl}/portal/changelog/unread`, { headers: this.identityHeaders() });\n if (!r.ok) return 0;\n return ((await r.json()) as { unread: number }).unread;\n }\n\n /**\n * Ask the server whether a survey is due for this person and, if so, show\n * it after its delay. Call once per page, after identify. Resolves to the\n * survey's slug when one was shown.\n */\n async surveys(options: SurveyOptions = {}): Promise<string | null> {\n const r = await this.fetchImpl(`${this.apiUrl}/portal/surveys/eligible`, { headers: this.identityHeaders() }).catch(() => undefined);\n if (!r?.ok) return null;\n const { survey } = (await r.json()) as { survey: EligibleSurvey | null };\n if (!survey || !surveyAllowedHere(document.location.pathname, survey)) return null;\n const portal = await this.portalUrl();\n const identity = { jwt: this.jwt, anonymousId: this.anonymousId() };\n await new Promise((resolve) => setTimeout(resolve, (survey.delivery.delaySeconds ?? 0) * 1000));\n this.surveyHandle?.close();\n this.surveyHandle = showSurvey(document, portal, survey, identity, options);\n return survey.slug;\n }\n\n /** Open one survey by slug as a modal, whatever its targeting says. */\n async survey(slug: string, options: SurveyOptions = {}): Promise<OpenHandle> {\n const portal = await this.portalUrl();\n this.surveyHandle?.close();\n this.surveyHandle = showSurvey(document, portal, { id: \"\", slug, delivery: { widget: \"modal\" }, pages: null }, { jwt: this.jwt, anonymousId: this.anonymousId() }, options);\n return this.surveyHandle;\n }\n}\n\nlet singleton: HarklyClient | undefined;\n\nexport function init(options: InitOptions): HarklyClient {\n singleton = new HarklyClient(options);\n return singleton;\n}\n\nfunction current(): HarklyClient {\n if (!singleton) throw new Error(\"Harkly: call init({ publicKey }) first\");\n return singleton;\n}\n\nexport const identify = (user: HarklyUser, options?: IdentifyOptions) => current().identify(user, options);\nexport const reset = () => current().reset();\nexport const feedback = (options?: Parameters<HarklyClient[\"feedback\"]>[0]) => current().feedback(options);\nexport const updates = (options?: UpdatesOptions) => current().updates(options);\nexport const unread = () => current().unread();\nexport const messenger = (options?: MessengerOptions) => current().messenger(options);\nexport const surveys = (options?: SurveyOptions) => current().surveys(options);\nexport const survey = (slug: string, options?: SurveyOptions) => current().survey(slug, options);\n\n"
|
|
8
9
|
],
|
|
9
|
-
"mappings": "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",
|
|
10
|
-
"debugId": "
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "0CC6414E5AA1971964756E2164756E21",
|
|
11
12
|
"names": []
|
|
12
13
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type OpenHandle, type WidgetIdentity } from "./widgets";
|
|
2
|
+
import { type MessengerDefaults } from "./messenger";
|
|
3
|
+
export type EligibleSurvey = {
|
|
4
|
+
id: string;
|
|
5
|
+
slug: string;
|
|
6
|
+
delivery: {
|
|
7
|
+
widget: "card" | "modal" | "off";
|
|
8
|
+
delaySeconds?: number;
|
|
9
|
+
};
|
|
10
|
+
pages: MessengerDefaults["pages"] | null;
|
|
11
|
+
};
|
|
12
|
+
export type SurveyOptions = {
|
|
13
|
+
position?: "right" | "left";
|
|
14
|
+
theme?: "light" | "dark" | "system";
|
|
15
|
+
onComplete?: (slug: string) => void;
|
|
16
|
+
onDismiss?: (slug: string) => void;
|
|
17
|
+
};
|
|
18
|
+
export declare function showSurvey(doc: Document, portal: string, survey: EligibleSurvey, identity: WidgetIdentity, options: SurveyOptions): OpenHandle;
|
|
19
|
+
export declare function surveyAllowedHere(pathname: string, survey: EligibleSurvey): boolean;
|
package/dist/widgets.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export type FeedbackOptions = {
|
|
|
10
10
|
export type UpdatesOptions = {
|
|
11
11
|
theme?: "light" | "dark" | "system";
|
|
12
12
|
};
|
|
13
|
-
export declare function widgetUrl(portalUrl: string, kind: "feedback" | "updates" | "messenger", options: Record<string, string | undefined>, identity: WidgetIdentity): string;
|
|
13
|
+
export declare function widgetUrl(portalUrl: string, kind: "feedback" | "updates" | "messenger" | "survey", options: Record<string, string | undefined>, identity: WidgetIdentity): string;
|
|
14
14
|
type Message = {
|
|
15
15
|
type: "harkly:close";
|
|
16
16
|
} | {
|
|
@@ -19,6 +19,9 @@ type Message = {
|
|
|
19
19
|
} | {
|
|
20
20
|
type: "harkly:height";
|
|
21
21
|
height: number;
|
|
22
|
+
} | {
|
|
23
|
+
type: "harkly:survey";
|
|
24
|
+
status: "completed" | "dismissed" | "none";
|
|
22
25
|
};
|
|
23
26
|
export declare function parseMessage(data: unknown): Message | null;
|
|
24
27
|
export type OpenHandle = {
|
|
@@ -27,6 +30,7 @@ export type OpenHandle = {
|
|
|
27
30
|
export declare function openFrame(doc: Document, src: string, origin: string, opts: {
|
|
28
31
|
side?: boolean;
|
|
29
32
|
onPosted?: (postId: string) => void;
|
|
33
|
+
onSurvey?: (status: "completed" | "dismissed" | "none") => void;
|
|
30
34
|
onClose?: () => void;
|
|
31
35
|
}): OpenHandle;
|
|
32
36
|
export {};
|