@arsel.sa/web-sdk 1.0.0 → 1.1.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/CHANGELOG.md +81 -0
- package/dist/arsel.js +1053 -329
- package/dist/arsel.js.map +1 -1
- package/dist/arsel.umd.cjs +107 -1
- package/dist/arsel.umd.cjs.map +1 -1
- package/dist/events.d.ts +2 -0
- package/dist/inapp-view.d.ts +16 -0
- package/dist/inapp.d.ts +83 -0
- package/dist/index.d.ts +20 -9
- package/dist/push.d.ts +16 -0
- package/dist/session.d.ts +5 -1
- package/dist/store.d.ts +30 -4
- package/dist/transport.d.ts +1 -1
- package/dist/types.d.ts +32 -0
- package/dist/version.d.ts +1 -1
- package/package.json +2 -1
- package/sw/arsel-sw.js +27 -2
package/dist/arsel.umd.cjs
CHANGED
|
@@ -1,2 +1,108 @@
|
|
|
1
|
-
(function(u,v){typeof exports=="object"&&typeof module<"u"?v(exports):typeof define=="function"&&define.amd?define(["exports"],v):(u=typeof globalThis<"u"?globalThis:u||self,v(u.Arsel={}))})(this,(function(u){"use strict";const v="arsel",m="events";let N=null;function oe(){return N||(N=new Promise((e,t)=>{const n=indexedDB.open(v,1);n.onupgradeneeded=()=>{const i=n.result;i.objectStoreNames.contains("kv")||i.createObjectStore("kv"),i.objectStoreNames.contains(m)||i.createObjectStore(m,{keyPath:"id",autoIncrement:!0})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}),N)}function y(e,t,n){return oe().then(i=>new Promise((s,a)=>{const o=n(i.transaction(e,t).objectStore(e));o.onsuccess=()=>s(o.result),o.onerror=()=>a(o.error)}))}function c(e){return y("kv","readonly",t=>t.get(e)).then(t=>t??null)}function d(e,t){return y("kv","readwrite",n=>n.put(t,e))}function k(e){return y("kv","readwrite",t=>t.delete(e))}function ce(e,t){return y(m,"readwrite",n=>n.add({body:e,idempotencyKey:t,createdAtMs:Date.now()}))}function le(){return y(m,"readonly",e=>e.getAll())}function ue(e){return y(m,"readwrite",t=>t.delete(e))}function de(){return y(m,"readonly",e=>e.count())}const r={clientKey:"client_key",baseUrl:"base_url",anonymousId:"anonymous_id",externalId:"external_id",email:"email",phoneNumber:"phone_number",installationId:"installation_id",deviceSecret:"device_secret",vapidKeyVersion:"vapid_key_version",endpoint:"endpoint",sessionStartedAt:"session_started_at",backgroundedAt:"backgrounded_at",lastResponseCode:"last_response_code",lastResponsePath:"last_response_path",lastResponseAtMs:"last_response_at"};async function T(){const e=await c(r.anonymousId);if(e)return e;const t=crypto.randomUUID();return await d(r.anonymousId,t),t}async function fe(){const e=crypto.randomUUID();return await d(r.anonymousId,e),e}const g="1.0.0",M={"X-Arsel-SDK":`web/${g}`},p={success:"success",retryable:"retryable",permanent:"permanent",reauth:"reauth"},R=-1;function pe(e,t){return e>=200&&e<=299?p.success:e===408||e===429||e>=500&&e<=599?p.retryable:t&&(e===401||e===403||e===404)?p.reauth:e===404?p.retryable:p.permanent}async function P(e,t){try{await Promise.all([d(r.lastResponseCode,t),d(r.lastResponsePath,e),d(r.lastResponseAtMs,Date.now())])}catch{}}async function $(e,t,n,i={},s=!1){let a;try{a=await fetch(e+t,{method:"POST",headers:{"Content-Type":"application/json",...M,...i},body:JSON.stringify(n),credentials:"omit",keepalive:!0})}catch{return await P(t,R),{result:p.retryable,code:R,body:null}}await P(t,a.status);const o=pe(a.status,s);let l=null;try{l=await a.json()}catch{}return{result:o,code:a.status,body:l}}async function j(e,t){try{const n=await fetch(e+t,{credentials:"omit",headers:M});return await P(t,n.status),n.ok?await n.json():null}catch{return await P(t,R),null}}const ye="/v1/events/send",S="arsel.",we=`${S}session_start`,me=`${S}session_end`,be=`${S}identify`,he=80,ve=128,ge=255,x=50,Se=8,W=64*1024;function V(e,t){if(e===null)return null;const n=typeof e;if(n==="string"||n==="boolean")return e;if(n==="number")return Number.isFinite(e)?e:String(e);if(n==="bigint")return String(e);if(e instanceof Date)return Number.isNaN(e.getTime())?void 0:e.toISOString();if(n!=="object"||t>=Se)return;if(Array.isArray(e))return e.map(s=>V(s,t+1)??null);const i={};for(const[s,a]of Object.entries(e)){if(!s)continue;const o=V(a,t+1);o!==void 0&&(i[s]=o)}return i}function Ee(e){const t={};let n=2,i=!1;for(const[s,a]of Object.entries(e??{})){if(!s)continue;const o=V(a,0);if(o===void 0)continue;const l=s.length+JSON.stringify(o).length+6;if(n+l>W){i=!0;continue}n+=l,t[s]=o}return i&&console.warn(`[arsel] event data exceeded ${W} serialized bytes — oversized properties were dropped`),t}async function _e(e,t,n){const[i,s,a,o]=await Promise.all([T(),c(r.externalId),c(r.email),c(r.phoneNumber)]),l={event:e.slice(0,he),anonymous_id:i.slice(0,ve),data:Ee(t),timestamp:new Date(n).toISOString()};return s&&(l.external_id=s.slice(0,ge)),a&&(l.email=a),o&&(l.phone_number=o),JSON.stringify(l)}async function E(e,t,n=Date.now()){await ce(await _e(e,t,n),crypto.randomUUID()),A().catch(()=>{})}let _=null;function A(){return _||(_=Ne().finally(()=>{_=null}),_)}function Ae(e){const t=e[0].idempotencyKey;return e.length===1?t:`${t}:${e[e.length-1].idempotencyKey}:${e.length}`}function Ie(e,t,n){e.some(s=>s.external_id||s.email||s.phone_number)&&console.error(`[arsel] ${e.length} event(s) carrying identifiers were rejected permanently (HTTP ${t}) and dropped. Response: ${JSON.stringify(n)}`)}async function Ne(){const[e,t]=await Promise.all([c(r.clientKey),c(r.baseUrl)]);if(!(!e||!t))for(;;){const n=await le();if(n.length===0)return;for(let i=0;i<n.length;i+=x){const s=n.slice(i,i+x),a=s.map(l=>JSON.parse(l.body)),o=await $(t,ye,s.length===1?a[0]:{events:a},{Authorization:`Bearer ${e}`,"Idempotency-Key":Ae(s)});if(o.result===p.retryable)return;o.result!==p.success&&Ie(a,o.code,o.body);for(const l of s)l.id!==void 0&&await ue(l.id)}}}function B(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),n=atob(t+"=".repeat((4-t.length%4)%4)),i=new Uint8Array(n.length);for(let s=0;s<n.length;s+=1)i[s]=n.charCodeAt(s);return i.buffer}function b(){return typeof navigator<"u"&&"serviceWorker"in navigator&&typeof PushManager<"u"&&typeof Notification<"u"}function F(e){return`/api/v1/orgs/${e}/push/web/config`}function C(e){return`/api/v1/orgs/${e}/push/subscriptions`}const X=1e4;let h="none",I=null,O=null;function ke(){h="external"}async function Te(e){if(b()){h="managed";try{I=await navigator.serviceWorker.register(e),O=null}catch(t){I=null,O=`service worker registration failed for '${e}': ${String(t)}. Check that the file is deployed and served with a JavaScript content type.`}}}function Pe(e,t){return e.active?Promise.resolve(e):new Promise((n,i)=>{const s=setTimeout(()=>{i(new Error(`service worker did not activate within ${t}ms — check the worker script for load errors in DevTools → Application → Service Workers`))},t),a=l=>{l.addEventListener("statechange",()=>{l.state==="activated"?(clearTimeout(s),n(e)):l.state==="redundant"&&(clearTimeout(s),i(new Error("service worker became redundant before activating — its script likely failed to parse")))})},o=e.installing??e.waiting;o?a(o):e.addEventListener("updatefound",()=>{e.installing&&a(e.installing)})})}function Oe(e,t,n){return Promise.race([e,new Promise((i,s)=>{setTimeout(()=>s(new Error(n)),t)})])}async function U(e=X){if(h==="none")throw new Error("push is not configured — pass serviceWorkerPath to init(), or serviceWorker: 'external' if your own service worker imports arsel-sw.js");if(h==="external")return Oe(navigator.serviceWorker.ready,e,`no service worker became active within ${e}ms — with serviceWorker: 'external', your own worker must be registered and must importScripts arsel-sw.js`);if(O)throw new Error(O);if(!I)throw new Error("service worker registration has not completed");return Pe(I,e)}async function Ke(e=X){try{return await U(e),null}catch(t){return t instanceof Error?t.message:String(t)}}async function De(){const[e,t]=await Promise.all([c(r.clientKey),c(r.baseUrl)]);if(!e||!t||!b())return!1;const n=await j(t,F(e));if(!(n!=null&&n.vapidPublicKey))return!1;let i;try{i=await U()}catch(a){return console.error(`[arsel] ${a instanceof Error?a.message:a}`),!1}const s=await i.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:B(n.vapidPublicKey)});return H(s,n.keyVersion)}async function H(e,t){var D;const[n,i,s]=await Promise.all([c(r.clientKey),c(r.baseUrl),T()]);if(!n||!i)return!1;let a=await c(r.installationId);a||(a=crypto.randomUUID(),await d(r.installationId,a));const o=e.toJSON(),l=await $(i,C(n),{installationId:a,platform:"web",endpoint:o.endpoint,keys:o.keys,anonymousId:s,enablementStatus:Notification.permission==="granted"?"AUTHORIZED":"DENIED",deviceTimezone:Intl.DateTimeFormat().resolvedOptions().timeZone,deviceLocale:navigator.language});return l.result!==p.success?!1:((D=l.body)!=null&&D.deviceSecret&&await d(r.deviceSecret,l.body.deviceSecret),await d(r.vapidKeyVersion,t),await d(r.endpoint,o.endpoint??null),!0)}async function Re(){const[e,t,n,i]=await Promise.all([c(r.clientKey),c(r.baseUrl),c(r.installationId),c(r.deviceSecret)]);return!e||!t||!n||!i?!1:(await $(t,`${C(e)}/unsubscribe`,{installationId:n},{"X-Arsel-Device-Auth":i},!0)).result===p.success}async function $e(){if(h==="none"||!b()||Notification.permission!=="granted")return;const[e,t]=await Promise.all([c(r.clientKey),c(r.baseUrl)]);if(!e||!t)return;const n=await j(t,F(e));if(!(n!=null&&n.vapidPublicKey))return;let i;try{i=await U()}catch{return}const s=await i.pushManager.getSubscription(),a=await c(r.vapidKeyVersion);if(s&&a===n.keyVersion)return;s&&await s.unsubscribe().catch(()=>!1);const o=await i.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:B(n.vapidPublicKey)});await H(o,n.keyVersion)}async function Ve(){if(!b())return!1;try{const e=h==="managed"?I:await navigator.serviceWorker.getRegistration();return e?await e.pushManager.getSubscription()!==null:!1}catch{return!1}}const Ue=30*6e4;async function L(e=Date.now()){const t=await c(r.sessionStartedAt)??0,n=await c(r.backgroundedAt)??0;if(t!==0){if(n===0||e-n<Ue)return;await E(me,{duration_seconds:Math.round((n-t)/1e3)},n)}await d(r.sessionStartedAt,e),await d(r.backgroundedAt,0),await E(we,{},e)}async function z(e=Date.now()){(await c(r.sessionStartedAt)??0)!==0&&await d(r.backgroundedAt,e)}function Me(){typeof document>"u"||(document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?L():z()}),window.addEventListener("pagehide",()=>void z()))}let f=null,J=!1;function w(e){J&&console.info(`[arsel] ${e}`)}const je=/^\+[1-9]\d{6,14}$/,xe=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,q=100;let K=[],Y=!1;function We(){typeof window<"u"&&window.addEventListener("online",()=>void A().catch(()=>{})),typeof document<"u"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&A().catch(()=>{})})}function Z(e){return f||(f=(async()=>{var a;if(!e.clientKey)throw new Error("Arsel: clientKey is required");const t=/^http:\/\/(localhost|127\.0\.0\.1)(:\d+)?(\/|$)/.test(e.baseUrl??"");if(!((a=e.baseUrl)!=null&&a.startsWith("https://"))&&!t)throw new Error("Arsel: baseUrl must be HTTPS (http is allowed for localhost only)");J=e.debug??!1;const n=e.baseUrl.replace(/\/+$/,"");await Promise.all([d(r.clientKey,e.clientKey),d(r.baseUrl,n)]),await T();const i=K;K=[];for(const o of i)await E(o.name,o.properties,o.timestampMs);e.serviceWorker==="external"?ke():e.serviceWorkerPath&&await Te(e.serviceWorkerPath),Me(),We();const s=typeof document<"u"?document:void 0;(s==null?void 0:s.visibilityState)==="visible"&&s.prerendering!==!0&&await L(),A(),$e(),w(`initialized (sdk ${g})`)})(),f)}async function G(e,t={}){const n=e==null?void 0:e.trim();if(!n){w("track() called with a blank event name — ignoring");return}if(n.startsWith(S)){w(`'${S}' is reserved for the SDK — ignoring '${n}'`);return}if(!f){if(K.length>=q){Y||(Y=!0,console.warn(`[arsel] more than ${q} events tracked before init() — dropping the rest. Call init() earlier.`));return}K.push({name:n,properties:t,timestampMs:Date.now()});return}await f,await E(n,t)}async function Q(e){await f;let{email:t,phoneNumber:n}=e??{};const i=e==null?void 0:e.externalId;if(t&&!xe.test(t)&&(console.error(`[arsel] identify(): '${t}' is not a valid email address — ignored`),t=void 0),n&&!je.test(n)&&(console.error(`[arsel] identify(): '${n}' is not E.164 (e.g. +966501234567) — ignored`),n=void 0),!i&&!t&&!n){w("identify() needs at least one of externalId, email or phoneNumber");return}i&&await d(r.externalId,i),t&&await d(r.email,t),n&&await d(r.phoneNumber,n),await E(be,{})}async function ee(){await f,await Promise.all([k(r.externalId),k(r.email),k(r.phoneNumber),k(r.sessionStartedAt)]),await fe(),w("identity reset")}async function te(){await f;const e=await Re();return w(e?"push opt-out recorded":"push opt-out not sent — no registration to revoke"),e}async function ne(){if(await f,!b())return!1;const e=await Ke();if(e)return console.error(`[arsel] promptForPush(): ${e}`),!1;const t=await Notification.requestPermission();return t!=="granted"?(w(`notification permission: ${t}`),!1):De()}async function re(){return await f,T()}async function ie(){const[e,t,n,i,s,a,o,l,D,Be,Fe,Ce]=await Promise.all([c(r.anonymousId),c(r.externalId),c(r.email),c(r.phoneNumber),c(r.installationId),c(r.deviceSecret),c(r.vapidKeyVersion),de(),Ve(),c(r.lastResponseCode),c(r.lastResponsePath),c(r.lastResponseAtMs)]);return{sdkVersion:g,initialized:f!==null,anonymousId:e,hasAssertedIdentity:!!(t||n||i),installationId:s,hasDeviceSecret:!!a,pendingEvents:l,permission:b()?Notification.permission:"unsupported",isSubscribed:D,vapidKeyVersion:o,lastResponseCode:Be,lastResponsePath:Fe,lastResponseAtMs:Ce}}async function se(){await f,await A()}const ae={init:Z,track:G,identify:Q,reset:ee,optOut:te,promptForPush:ne,getAnonymousId:re,diagnostics:ie,flushNow:se,SDK_VERSION:g};u.Arsel=ae,u.SDK_VERSION=g,u.default=ae,u.diagnostics=ie,u.flushNow=se,u.getAnonymousId=re,u.identify=Q,u.init=Z,u.optOut=te,u.promptForPush=ne,u.reset=ee,u.track=G,Object.defineProperties(u,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|
|
1
|
+
(function(m,$){typeof exports=="object"&&typeof module<"u"?$(exports):typeof define=="function"&&define.amd?define(["exports"],$):(m=typeof globalThis<"u"?globalThis:m||self,$(m.Arsel={}))})(this,(function(m){"use strict";const $="arsel",v={events:"events",inAppBeacons:"inapp_beacons"};let Y=null;function at(){return Y||(Y=new Promise((e,t)=>{const n=indexedDB.open($,2);n.onupgradeneeded=()=>{const i=n.result;i.objectStoreNames.contains("kv")||i.createObjectStore("kv");for(const r of Object.values(v))i.objectStoreNames.contains(r)||i.createObjectStore(r,{keyPath:"id",autoIncrement:!0})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}),Y)}function N(e,t,n){return at().then(i=>new Promise((r,s)=>{const a=n(i.transaction(e,t).objectStore(e));a.onsuccess=()=>r(a.result),a.onerror=()=>s(a.error)}))}function c(e){return N("kv","readonly",t=>t.get(e)).then(t=>t??null)}function u(e,t){return N("kv","readwrite",n=>n.put(t,e))}function K(e){return N("kv","readwrite",t=>t.delete(e))}function ve(e,t,n=""){return N(e,"readwrite",i=>i.add({body:t,idempotencyKey:n,createdAtMs:Date.now()}))}function oe(e){return N(e,"readonly",t=>t.getAll())}function se(e,t){return N(e,"readwrite",n=>n.delete(t))}function Se(e){return N(e,"readonly",t=>t.count())}async function ct(e,t){const n=await oe(e);if(!(n.length<=t))for(const i of n.slice(0,n.length-t))i.id!==void 0&&await se(e,i.id)}const o={clientKey:"client_key",baseUrl:"base_url",anonymousId:"anonymous_id",externalId:"external_id",email:"email",phoneNumber:"phone_number",installationId:"installation_id",deviceSecret:"device_secret",vapidKeyVersion:"vapid_key_version",endpoint:"endpoint",subscriptionStatus:"subscription_status",sessionStartedAt:"session_started_at",backgroundedAt:"backgrounded_at",lastResponseCode:"last_response_code",lastResponsePath:"last_response_path",lastResponseAtMs:"last_response_at",inAppBundle:"inapp_bundle",inAppState:"inapp_state",inAppSession:"inapp_session"};async function L(){const e=await c(o.anonymousId);if(e)return e;const t=crypto.randomUUID();return await u(o.anonymousId,t),t}async function lt(){const e=crypto.randomUUID();return await u(o.anonymousId,e),e}const V="1.1.0",Ae={"X-Arsel-SDK":`web/${V}`},b={success:"success",retryable:"retryable",permanent:"permanent",reauth:"reauth"},J=-1;function Ee(e,t){return e>=200&&e<=299?b.success:e===408||e===429||e>=500&&e<=599?b.retryable:t&&(e===401||e===403||e===404)?b.reauth:e===404?b.retryable:b.permanent}async function G(e,t){try{await Promise.all([u(o.lastResponseCode,t),u(o.lastResponsePath,e),u(o.lastResponseAtMs,Date.now())])}catch{}}async function F(e,t,n,i={},r=!1){let s;try{s=await fetch(e+t,{method:"POST",headers:{"Content-Type":"application/json",...Ae,...i},body:JSON.stringify(n),credentials:"omit",keepalive:!0})}catch{return await G(t,J),{result:b.retryable,code:J,body:null}}await G(t,s.status);const a=Ee(s.status,r);let l=null;try{l=await s.json()}catch{}return{result:a,code:s.status,body:l}}async function ae(e,t,n={},i=!1,r={}){let s;try{s=await fetch(e+t,{...r,credentials:"omit",headers:{...Ae,...n}})}catch{return await G(t,J),{result:b.retryable,code:J,body:null}}await G(t,s.status);let a=null;try{a=await s.json()}catch{}return{result:Ee(s.status,i),code:s.status,body:a}}const ut="/v1/events/send",T="arsel.",dt=`${T}session_start`,ft=`${T}session_end`,pt=`${T}identify`,mt=`${T}screen`,yt=80,bt=128,ht=255,Ie=50,gt=8,_e=64*1024;function ce(e,t){if(e===null)return null;const n=typeof e;if(n==="string"||n==="boolean")return e;if(n==="number")return Number.isFinite(e)?e:String(e);if(n==="bigint")return String(e);if(e instanceof Date)return Number.isNaN(e.getTime())?void 0:e.toISOString();if(n!=="object"||t>=gt)return;if(Array.isArray(e))return e.map(r=>ce(r,t+1)??null);const i={};for(const[r,s]of Object.entries(e)){if(!r)continue;const a=ce(s,t+1);a!==void 0&&(i[r]=a)}return i}function wt(e){const t={};let n=2,i=!1;for(const[r,s]of Object.entries(e??{})){if(!r)continue;const a=ce(s,0);if(a===void 0)continue;const l=r.length+JSON.stringify(a).length+6;if(n+l>_e){i=!0;continue}n+=l,t[r]=a}return i&&console.warn(`[arsel] event data exceeded ${_e} serialized bytes — oversized properties were dropped`),t}async function vt(e,t,n){const[i,r,s,a]=await Promise.all([L(),c(o.externalId),c(o.email),c(o.phoneNumber)]),l={event:e.slice(0,yt),anonymous_id:i.slice(0,bt),data:wt(t),timestamp:new Date(n).toISOString()};return r&&(l.external_id=r.slice(0,ht)),s&&(l.email=s),a&&(l.phone_number=a),JSON.stringify(l)}async function P(e,t,n=Date.now()){await ve(v.events,await vt(e,t,n),crypto.randomUUID()),W().catch(()=>{})}let j=null;function W(){return j||(j=Et().finally(()=>{j=null}),j)}function St(e){const t=e[0].idempotencyKey;return e.length===1?t:`${t}:${e[e.length-1].idempotencyKey}:${e.length}`}function At(e,t,n){e.some(r=>r.external_id||r.email||r.phone_number)&&console.error(`[arsel] ${e.length} event(s) carrying identifiers were rejected permanently (HTTP ${t}) and dropped. Response: ${JSON.stringify(n)}`)}async function Et(){const[e,t]=await Promise.all([c(o.clientKey),c(o.baseUrl)]);if(!(!e||!t))for(;;){const n=await oe(v.events);if(n.length===0)return;for(let i=0;i<n.length;i+=Ie){const r=n.slice(i,i+Ie),s=r.map(l=>JSON.parse(l.body)),a=await F(t,ut,r.length===1?s[0]:{events:s},{Authorization:`Bearer ${e}`,"Idempotency-Key":St(r)});if(a.result===b.retryable)return;a.result!==b.success&&At(s,a.code,a.body);for(const l of r)l.id!==void 0&&await se(v.events,l.id)}}}const Z=1e3,It=720*60*60*Z,_t=500,Ne=50,Nt=86400,xt=900,Q={maxPerSession:1,maxLifetime:3,minSecondsBetween:86400,delaySeconds:0},kt=["MODAL","BANNER_TOP","BANNER_BOTTOM","IMAGE_ONLY"];let le=!1,d=null,g={},S={startedAt:0,counts:{}},X=null,z=null,xe=!1,ue=null,x=null,ke=!1,Te=!1;function k(e){ke&&console.info(`[arsel] in-app: ${e}`)}async function Tt(e){le=!0,ke=e;const[t,n,i]=await Promise.all([c(o.inAppBundle),c(o.inAppState),c(o.inAppSession)]);d=t,g=n??{},S=i??{startedAt:0,counts:{}},await Be(),await ee()}function Pt(e){x=e}function Dt(e){xe=e,e&&fe()}function Ot(){return{messages:(d==null?void 0:d.messages.length)??0,bundleVersion:(d==null?void 0:d.bundleVersion)??null,fetchedAtMs:(d==null?void 0:d.fetchedAtMs)??null}}function Mt(){return Se(v.inAppBeacons)}async function Pe(){d=null,await K(o.inAppBundle),le&&await ee(!0)}function Rt(){ee(!0)}function ee(e=!1){return ue??(ue=Ut(e).finally(()=>{ue=null})),ue}async function Ut(e){if(!le)return;const t=Date.now();if(!e&&d&&t-d.fetchedAtMs<d.ttlSeconds*Z)return;const n=await Oe();if(!n)return;const i=Bt(n.clientKey,n.installationId),r={"X-Arsel-Device-Auth":n.deviceSecret},s=!!(d!=null&&d.bundleVersion);s&&(r["If-None-Match"]=`"${(d==null?void 0:d.bundleVersion)??""}"`);let a=await De(n.baseUrl,i,r);if(a.code===Yt&&s&&Te&&(k("conditional request failed; retrying without If-None-Match"),delete r["If-None-Match"],a=await De(n.baseUrl,i,r)),a.code===Jt){d&&(d={...d,fetchedAtMs:t},await u(o.inAppBundle,d));return}if(a.result!==b.success||!a.body)return;s||(Te=!0);const l=Ct(a.body,t);l&&(d=l,await u(o.inAppBundle,d),await Ht(l,t))}function De(e,t,n){return ae(e,t,n,!0,{cache:"no-store"})}function Bt(e,t){const n=encodeURIComponent(e),i=encodeURIComponent(t);return`/api/v1/orgs/${n}/in-app/bundle?installationId=${i}`}async function Oe(){const[e,t,n,i]=await Promise.all([c(o.clientKey),c(o.baseUrl),c(o.installationId),c(o.deviceSecret)]);return!e||!t||!n||!i?null:{clientKey:e,baseUrl:t,installationId:n,deviceSecret:i}}function Ct(e,t){if(typeof(e==null?void 0:e.bundleVersion)!="string")return k("response carried no bundleVersion"),null;e.contractVersion!==void 0&&e.contractVersion!==1&&k(`unknown contractVersion ${String(e.contractVersion)}; proceeding`);const n=Array.isArray(e.messages)?e.messages:[],i=[];for(const s of n){const a=$t(s);a&&i.push(a)}n.length!==i.length&&k(`dropped ${n.length-i.length} unrenderable message(s)`);const r=O(e.ttlSeconds);return{bundleVersion:e.bundleVersion,ttlSeconds:r&&r>0?r:xt,fetchedAtMs:t,messages:i}}function $t(e){if(!D(e))return null;const t=y(e.campaignId),n=y(e.messageId),i=y(e.layout),r=D(e.content)?e.content:null,s=r?y(r.headline):void 0;if(!t||!n||!i||!r||!s)return k("message missing a required field"),null;if(!kt.includes(i))return k(`layout ${i} is not renderable on web`),null;const a=D(e.trigger)?e.trigger:{},l=D(e.displayRules)?e.displayRules:{};return{campaignId:t,messageId:n,variantKey:y(e.variantKey)??"default",priority:O(e.priority)??0,expiresAtMs:qt(e.expiresAt),triggerType:y(a.type)??"APP_OPEN",triggerEventName:y(a.eventName)??null,triggerProperties:D(a.properties)?a.properties:null,displayRules:{maxPerSession:O(l.maxPerSession)??Q.maxPerSession,maxLifetime:O(l.maxLifetime)??Q.maxLifetime,minSecondsBetween:O(l.minSecondsBetween)??Q.minSecondsBetween,delaySeconds:O(l.delaySeconds)??Q.delaySeconds},layout:i,content:{headline:s,body:y(r.body)??"",imageUrl:y(r.imageUrl),backgroundColor:y(r.backgroundColor),textColor:y(r.textColor),showCloseButton:r.showCloseButton!==!1},buttons:Array.isArray(e.buttons)?e.buttons.map(Kt).filter(w=>w!==null):[]}}function Kt(e){if(!D(e))return null;const t=y(e.buttonId),n=y(e.label),i=y(e.action);return!t||!n||!i?null:{buttonId:t,label:n,action:i,value:y(e.value),style:y(e.style)==="SECONDARY"?"SECONDARY":"PRIMARY"}}function Lt(e,t,n,i){if(xe||X!==null||!d)return null;for(const r of d.messages){if(r.triggerType!==t||t!=="APP_OPEN"&&r.triggerEventName!==n||!Vt(r.triggerProperties,i))continue;const s=g[r.messageId];if(r.expiresAtMs!==null&&r.expiresAtMs<=e){zt(r);continue}if(!(((s==null?void 0:s.shown)??0)>=r.displayRules.maxLifetime)&&!((S.counts[r.messageId]??0)>=r.displayRules.maxPerSession)&&!(s&&e-s.lastShownAtMs<r.displayRules.minSecondsBetween*Z))return r}return null}function Vt(e,t){if(!e)return!0;const n=t;for(const[i,r]of Object.entries(e))if(String(n[i])!==String(r))return!1;return!0}function de(e,t,n={}){try{const i=Lt(Date.now(),e,t,n);if(!i)return;X=i.messageId,Me=t;const r=i.displayRules.delaySeconds*Z;if(r<=0){x==null||x(i);return}z=setTimeout(()=>{z=null,x==null||x(i)},r)}catch(i){k(`observe failed: ${i instanceof Error?i.message:"unknown"}`),X=null}}let Me=null;function Ft(){return Me}function Re(){Be().then(()=>{de("APP_OPEN",null,{})})}function fe(){z!==null&&(clearTimeout(z),z=null,X=null)}function Ue(){X=null}async function jt(e,t){const n=Date.now(),i=g[e.messageId]??{shown:0,lastShownAtMs:0,lastSeenInBundleAtMs:n};g={...g,[e.messageId]:{...i,shown:i.shown+1,lastShownAtMs:n}},S={...S,counts:{...S.counts,[e.messageId]:(S.counts[e.messageId]??0)+1}},await Promise.all([u(o.inAppState,g),u(o.inAppSession,S)]),await te(e,"impression",{triggerEventName:t})}async function Wt(e,t){await te(e,"clicked",{buttonId:t})}async function Xt(e,t){await te(e,"dismissed",{visibleSeconds:Math.max(0,Math.min(Nt,Math.round(t)))})}function zt(e){const t=g[e.messageId];t!=null&&t.expiredReported||(g={...g,[e.messageId]:{shown:(t==null?void 0:t.shown)??0,lastShownAtMs:(t==null?void 0:t.lastShownAtMs)??0,lastSeenInBundleAtMs:(t==null?void 0:t.lastSeenInBundleAtMs)??Date.now(),expiredReported:!0}},u(o.inAppState,g),te(e,"expired",{}))}async function te(e,t,n){const i={messageId:e.messageId,campaignId:e.campaignId,eventType:t,timestamp:new Date().toISOString(),variantKey:e.variantKey};n.buttonId&&(i.buttonId=n.buttonId),n.visibleSeconds!==void 0&&(i.visibleSeconds=n.visibleSeconds),n.triggerEventName&&(i.triggerEventName=n.triggerEventName),await ve(v.inAppBeacons,JSON.stringify(i)),await ct(v.inAppBeacons,_t),ne()}async function ne(){const e=await Oe();if(!e)return;const t=await oe(v.inAppBeacons);if(t.length===0)return;const n=`/api/v1/orgs/${encodeURIComponent(e.clientKey)}/in-app/events`;for(let i=0;i<t.length;i+=Ne){const r=t.slice(i,i+Ne);if((await F(e.baseUrl,n,{installationId:e.installationId,events:r.map(a=>JSON.parse(a.body))},{"X-Arsel-Device-Auth":e.deviceSecret},!0)).result===b.retryable)return;for(const a of r)a.id!==void 0&&await se(v.inAppBeacons,a.id)}}async function Ht(e,t){const n=new Set(e.messages.map(r=>r.messageId)),i={};for(const[r,s]of Object.entries(g)){const a=n.has(r)?t:s.lastSeenInBundleAtMs;t-a>It||(i[r]={...s,lastSeenInBundleAtMs:a})}g=i,await u(o.inAppState,g)}async function Be(){const e=await c(o.sessionStartedAt)??0;S.startedAt!==e&&(S={startedAt:e,counts:{}},await u(o.inAppSession,S))}function D(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function y(e){return typeof e=="string"&&e.length>0?e:void 0}function O(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function qt(e){if(typeof e!="string")return null;const t=Date.parse(e);return Number.isNaN(t)?null:t}const Yt=-1,Jt=304,Gt=2147483e3,pe=44,Ce=/^#[0-9a-fA-F]{3,8}$/,Zt=.6;let $e=null,Qt=0;function en(e,t,n){const i=e.layout==="MODAL",r=Date.now(),s=`arsel-iam-${Qt+=1}`,a=document.createElement("div");a.setAttribute("data-arsel-inapp","");const l=a.attachShadow({mode:"closed"});fn(l),a.style.setProperty("z-index",String(t.zIndex||Gt)),a.style.setProperty("isolation","isolate"),a.setAttribute("data-layout",e.layout),a.setAttribute("dir",ln());const w=document.activeElement instanceof HTMLElement?document.activeElement:null,f=document.createElement("div");f.className="panel",f.tabIndex=-1,i?(f.setAttribute("role","dialog"),f.setAttribute("aria-modal","true"),f.setAttribute("aria-labelledby",`${s}-h`),e.content.body&&f.setAttribute("aria-describedby",`${s}-b`)):(f.setAttribute("role","status"),f.setAttribute("aria-live","polite"));const I=un(e);I.background&&f.style.setProperty("background",I.background),I.text&&f.style.setProperty("color",I.text);let q=!1;const _=p=>{var A,st;q||(q=!0,document.removeEventListener("keydown",C,!0),a.remove(),w!=null&&w.isConnected?w.focus():i&&((st=(A=document.body).focus)==null||st.call(A)),p==="dismiss"&&n.onDismiss((Date.now()-r)/1e3))},C=p=>{p.key==="Escape"&&(p.stopPropagation(),_("dismiss"))};if(e.layout==="IMAGE_ONLY"&&e.content.imageUrl)f.append(nn(e,()=>Un(e)));else{e.content.imageUrl&&f.append(tn(e.content.imageUrl,e.content.headline));const p=document.createElement("h2");if(p.id=`${s}-h`,p.className="headline",p.textContent=e.content.headline,f.append(p),e.content.body){const A=document.createElement("p");A.id=`${s}-b`,A.className="body",A.textContent=e.content.body,f.append(A)}}if(e.buttons.length>0&&f.append(rn(e,n,_)),(e.content.showCloseButton||!e.buttons.some(p=>p.action==="DISMISS"))&&f.append(an(t.closeLabel,()=>_("dismiss"))),i){const p=document.createElement("div");p.className="backdrop",e.content.showCloseButton&&p.addEventListener("click",()=>_("dismiss")),l.append(p)}l.append(f),document.body.append(a),i?(f.focus({preventScroll:!0}),l.addEventListener("keydown",p=>{p instanceof KeyboardEvent&&cn(p,l)})):(f.textContent,f.setAttribute("aria-busy","true"),requestAnimationFrame(()=>{f.removeAttribute("aria-busy")})),document.addEventListener("keydown",C,!0),requestAnimationFrame(()=>{q||!a.isConnected||document.visibilityState==="visible"&&n.onImpression()});function Un(p){const A=p.buttons[0];if(!A){_("dismiss");return}n.onButton(A),_("button")}return{close:_,root:l}}function tn(e,t){const n=document.createElement("figure");n.className="figure";const i=document.createElement("img");return i.src=e,i.alt=t,i.loading="eager",i.decoding="async",i.referrerPolicy="no-referrer",i.addEventListener("error",()=>n.remove()),n.append(i),n}function nn(e,t){const n=document.createElement("button");n.type="button",n.className="image-only";const i=document.createElement("img");return i.src=e.content.imageUrl??"",i.alt=e.content.headline,i.loading="eager",i.decoding="async",i.referrerPolicy="no-referrer",n.append(i),n.addEventListener("click",t),n}function rn(e,t,n){const i=document.createElement("div");i.className="buttons";for(const r of e.buttons){const s=r.action==="URL"&&r.value?on(r):sn(r);s.addEventListener("click",()=>{r.action!=="DISMISS"&&t.onButton(r),n(r.action==="DISMISS"?"dismiss":"button"),r.action==="DEEP_LINK"&&r.value&&location.assign(r.value)}),i.append(s)}return i}function on(e){const t=document.createElement("a");return t.href=e.value??"#",t.target="_blank",t.rel="noopener noreferrer",t.className=`cta ${e.style.toLowerCase()}`,t.textContent=e.label,t}function sn(e){const t=document.createElement("button");return t.type="button",t.className=`cta ${e.style.toLowerCase()}`,t.textContent=e.label,t}function an(e,t){const n=document.createElement("button");return n.type="button",n.className="close",n.setAttribute("aria-label",e),n.textContent="×",n.addEventListener("click",t),n}function cn(e,t){if(e.key!=="Tab")return;const n=[...t.querySelectorAll("button, a[href]")].filter(a=>!a.hasAttribute("disabled"));if(n.length===0)return;const i=n[0],r=n[n.length-1];if(!i||!r)return;const s=t.activeElement;if(e.shiftKey&&s===i){e.preventDefault(),r.focus();return}!e.shiftKey&&s===r&&(e.preventDefault(),i.focus())}function ln(){const e=document.documentElement.getAttribute("dir");if(e)return e;try{return getComputedStyle(document.documentElement).direction||"ltr"}catch{return"ltr"}}function un(e){const t=Ce.test(e.content.backgroundColor??"")?e.content.backgroundColor:void 0,n=Ce.test(e.content.textColor??"")?e.content.textColor:void 0;return t&&!n?{background:t,text:dn(t)>Zt?"#101010":"#FFFFFF"}:{background:t,text:n}}function dn(e){const t=e.slice(1),n=t.length===3?t.split("").map(a=>a+a).join(""):t.slice(0,6),i=parseInt(n.slice(0,2),16)/255,r=parseInt(n.slice(2,4),16)/255,s=parseInt(n.slice(4,6),16)/255;return .2126*i+.7152*r+.0722*s}function fn(e){if("adoptedStyleSheets"in Document.prototype&&typeof CSSStyleSheet=="function")try{$e??($e=pn()),e.adoptedStyleSheets=[$e];return}catch{}const t=document.createElement("style");t.textContent=Ke,e.append(t)}function pn(){const e=new CSSStyleSheet;return e.replaceSync(Ke),e}const Ke=`
|
|
2
|
+
:host {
|
|
3
|
+
all: initial;
|
|
4
|
+
display: block;
|
|
5
|
+
position: fixed;
|
|
6
|
+
inset: 0;
|
|
7
|
+
pointer-events: none;
|
|
8
|
+
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
|
|
9
|
+
line-height: 1.5;
|
|
10
|
+
color: #101010;
|
|
11
|
+
}
|
|
12
|
+
.backdrop {
|
|
13
|
+
position: fixed;
|
|
14
|
+
inset: 0;
|
|
15
|
+
background: rgba(0, 0, 0, 0.45);
|
|
16
|
+
pointer-events: auto;
|
|
17
|
+
}
|
|
18
|
+
.panel {
|
|
19
|
+
position: fixed;
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
pointer-events: auto;
|
|
22
|
+
background: #ffffff;
|
|
23
|
+
border-radius: 12px;
|
|
24
|
+
padding: 20px;
|
|
25
|
+
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
|
|
26
|
+
max-height: calc(100vh - 32px);
|
|
27
|
+
overflow-y: auto;
|
|
28
|
+
}
|
|
29
|
+
:host([data-layout="MODAL"]) .panel {
|
|
30
|
+
inset-inline-start: 50%;
|
|
31
|
+
top: 50%;
|
|
32
|
+
transform: translate(-50%, -50%);
|
|
33
|
+
width: min(calc(100vw - 32px), 420px);
|
|
34
|
+
}
|
|
35
|
+
:host([dir="rtl"][data-layout="MODAL"]) .panel {
|
|
36
|
+
transform: translate(50%, -50%);
|
|
37
|
+
}
|
|
38
|
+
:host([data-layout="BANNER_TOP"]) .panel,
|
|
39
|
+
:host([data-layout="BANNER_BOTTOM"]) .panel {
|
|
40
|
+
inset-inline: 16px;
|
|
41
|
+
margin-inline: auto;
|
|
42
|
+
max-width: min(calc(100vw - 32px), 560px);
|
|
43
|
+
}
|
|
44
|
+
:host([data-layout="BANNER_TOP"]) .panel {
|
|
45
|
+
top: 16px;
|
|
46
|
+
padding-top: calc(20px + env(safe-area-inset-top));
|
|
47
|
+
}
|
|
48
|
+
:host([data-layout="BANNER_BOTTOM"]) .panel {
|
|
49
|
+
bottom: 16px;
|
|
50
|
+
padding-bottom: calc(20px + env(safe-area-inset-bottom));
|
|
51
|
+
}
|
|
52
|
+
:host([data-layout="IMAGE_ONLY"]) .panel {
|
|
53
|
+
inset-inline-start: 50%;
|
|
54
|
+
top: 50%;
|
|
55
|
+
transform: translate(-50%, -50%);
|
|
56
|
+
padding: 0;
|
|
57
|
+
background: transparent;
|
|
58
|
+
box-shadow: none;
|
|
59
|
+
}
|
|
60
|
+
.figure { margin: 0 0 12px; }
|
|
61
|
+
.figure img, .image-only img {
|
|
62
|
+
display: block;
|
|
63
|
+
width: 100%;
|
|
64
|
+
height: auto;
|
|
65
|
+
border-radius: 8px;
|
|
66
|
+
}
|
|
67
|
+
.image-only {
|
|
68
|
+
display: block;
|
|
69
|
+
padding: 0;
|
|
70
|
+
border: 0;
|
|
71
|
+
background: none;
|
|
72
|
+
cursor: pointer;
|
|
73
|
+
width: min(calc(100vw - 32px), 420px);
|
|
74
|
+
}
|
|
75
|
+
.headline { margin: 0 0 8px; font-size: 18px; font-weight: 600; }
|
|
76
|
+
.body { margin: 0 0 16px; font-size: 15px; }
|
|
77
|
+
.buttons { display: flex; gap: 8px; flex-wrap: wrap; }
|
|
78
|
+
.cta {
|
|
79
|
+
flex: 1 1 auto;
|
|
80
|
+
min-height: ${pe}px;
|
|
81
|
+
padding: 10px 16px;
|
|
82
|
+
border-radius: 8px;
|
|
83
|
+
border: 1px solid currentColor;
|
|
84
|
+
font: inherit;
|
|
85
|
+
cursor: pointer;
|
|
86
|
+
text-align: center;
|
|
87
|
+
text-decoration: none;
|
|
88
|
+
}
|
|
89
|
+
.cta.primary { background: #101010; color: #ffffff; border-color: #101010; }
|
|
90
|
+
.cta.secondary { background: transparent; color: inherit; }
|
|
91
|
+
.close {
|
|
92
|
+
position: absolute;
|
|
93
|
+
top: 4px;
|
|
94
|
+
inset-inline-end: 4px;
|
|
95
|
+
min-width: ${pe}px;
|
|
96
|
+
min-height: ${pe}px;
|
|
97
|
+
border: 0;
|
|
98
|
+
background: none;
|
|
99
|
+
color: inherit;
|
|
100
|
+
font-size: 22px;
|
|
101
|
+
line-height: 1;
|
|
102
|
+
cursor: pointer;
|
|
103
|
+
}
|
|
104
|
+
@media (prefers-reduced-motion: reduce) {
|
|
105
|
+
.panel { animation: none; transition: none; }
|
|
106
|
+
}
|
|
107
|
+
`,me="REVOKED";function mn(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),n=atob(t+"=".repeat((4-t.length%4)%4)),i=new Uint8Array(n.length);for(let r=0;r<n.length;r+=1)i[r]=n.charCodeAt(r);return i.buffer}function M(){return typeof navigator<"u"&&"serviceWorker"in navigator&&typeof PushManager<"u"&&typeof Notification<"u"}function Le(e){return`/api/v1/orgs/${e}/push/web/config`}function ye(e){return`/api/v1/orgs/${e}/push/subscriptions`}const Ve=1e4;let R="none",H=null,ie=null;function yn(){R="external"}async function bn(e){if(M()){R="managed";try{H=await navigator.serviceWorker.register(e),ie=null}catch(t){H=null,ie=`service worker registration failed for '${e}': ${String(t)}. Check that the file is deployed and served with a JavaScript content type.`}}}function hn(e,t){return e.active?Promise.resolve(e):new Promise((n,i)=>{const r=setTimeout(()=>{i(new Error(`service worker did not activate within ${t}ms — check the worker script for load errors in DevTools → Application → Service Workers`))},t),s=l=>{l.addEventListener("statechange",()=>{l.state==="activated"?(clearTimeout(r),n(e)):l.state==="redundant"&&(clearTimeout(r),i(new Error("service worker became redundant before activating — its script likely failed to parse")))})},a=e.installing??e.waiting;a?s(a):e.addEventListener("updatefound",()=>{e.installing&&s(e.installing)})})}function gn(e,t,n){return Promise.race([e,new Promise((i,r)=>{setTimeout(()=>r(new Error(n)),t)})])}async function be(e=Ve){if(R==="none")throw new Error("push is not configured — pass serviceWorkerPath to init(), or serviceWorker: 'external' if your own service worker imports arsel-sw.js");if(R==="external")return gn(navigator.serviceWorker.ready,e,`no service worker became active within ${e}ms — with serviceWorker: 'external', your own worker must be registered and must importScripts arsel-sw.js`);if(ie)throw new Error(ie);if(!H)throw new Error("service worker registration has not completed");return hn(H,e)}async function wn(e=Ve){try{return await be(e),null}catch(t){return t instanceof Error?t.message:String(t)}}async function Fe(e,t){try{return await e.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:mn(t)})}catch(n){return console.error(`[arsel] push subscribe failed: ${n instanceof Error?n.message:n}`),null}}async function vn(){const[e,t]=await Promise.all([c(o.clientKey),c(o.baseUrl)]);if(!e||!t||!M())return!1;const{body:n}=await ae(t,Le(e));if(!(n!=null&&n.vapidPublicKey))return!1;let i;try{i=await be()}catch(s){return console.error(`[arsel] ${s instanceof Error?s.message:s}`),!1}const r=await Fe(i,n.vapidPublicKey);return r?je(r,n.keyVersion):!1}async function je(e,t){var f,I;const[n,i,r]=await Promise.all([c(o.clientKey),c(o.baseUrl),L()]);if(!n||!i)return!1;let s=await c(o.installationId);s||(s=crypto.randomUUID(),await u(o.installationId,s));const a=e.toJSON(),l=await F(i,ye(n),{installationId:s,platform:"web",endpoint:a.endpoint,keys:a.keys,anonymousId:r,enablementStatus:Notification.permission==="granted"?"AUTHORIZED":"DENIED",deviceTimezone:Intl.DateTimeFormat().resolvedOptions().timeZone,deviceLocale:navigator.language});if(l.result!==b.success)return!1;(f=l.body)!=null&&f.deviceSecret&&await u(o.deviceSecret,l.body.deviceSecret),await u(o.vapidKeyVersion,t),await u(o.endpoint,a.endpoint??null);const w=((I=l.body)==null?void 0:I.status)??null;return await u(o.subscriptionStatus,w),w!==me}async function Sn(){const[e,t,n,i]=await Promise.all([c(o.clientKey),c(o.baseUrl),c(o.installationId),c(o.deviceSecret)]);return!e||!t||!n||!i||(await F(t,`${ye(e)}/unsubscribe`,{installationId:n},{"X-Arsel-Device-Auth":i},!0)).result!==b.success?!1:(await u(o.subscriptionStatus,me),!0)}async function An(){if(R==="none"||!M()||Notification.permission!=="granted")return;const[e,t]=await Promise.all([c(o.clientKey),c(o.baseUrl)]);if(!e||!t)return;const{body:n}=await ae(t,Le(e));if(!(n!=null&&n.vapidPublicKey))return;let i;try{i=await be()}catch{return}const r=await i.pushManager.getSubscription(),s=await c(o.vapidKeyVersion);if(r&&s===n.keyVersion)return;r&&await r.unsubscribe().catch(()=>!1);const a=await Fe(i,n.vapidPublicKey);a&&await je(a,n.keyVersion)}async function En(){if(!M()||await c(o.subscriptionStatus)===me)return!1;try{const e=R==="managed"?H:await navigator.serviceWorker.getRegistration();return e?await e.pushManager.getSubscription()!==null:!1}catch{return!1}}function In(){return he??(he=_n().finally(()=>{he=null})),he}let he=null;async function _n(){var s;const[e,t,n]=await Promise.all([c(o.clientKey),c(o.baseUrl),L()]);if(!e||!t)return!1;if(await c(o.deviceSecret))return!0;let i=await c(o.installationId);i||(i=crypto.randomUUID(),await u(o.installationId,i));const r=await F(t,ye(e),{installationId:i,platform:"web",anonymousId:n,enablementStatus:"NOT_DETERMINED",deviceTimezone:Intl.DateTimeFormat().resolvedOptions().timeZone,deviceLocale:navigator.language});return r.code===403?(console.error("[arsel] this origin is not on the organization's allowed origins list — in-app messaging is disabled"),!1):r.result!==b.success?!1:((s=r.body)!=null&&s.deviceSecret&&await u(o.deviceSecret,r.body.deviceSecret),!0)}const Nn=30*6e4;async function We(e=Date.now()){const t=await c(o.sessionStartedAt)??0,n=await c(o.backgroundedAt)??0;if(t!==0){if(n===0||e-n<Nn)return;await P(ft,{duration_seconds:Math.round((n-t)/1e3)},n)}await u(o.sessionStartedAt,e),await u(o.backgroundedAt,0),await P(dt,{},e)}async function Xe(e=Date.now()){(await c(o.sessionStartedAt)??0)!==0&&await u(o.backgroundedAt,e)}function xn(e){typeof document>"u"||(document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?We().then(()=>e==null?void 0:e()):Xe()}),window.addEventListener("pagehide",()=>void Xe()))}let h=null,ge=!1,U=null;function E(e){ge&&console.info(`[arsel] ${e}`)}const kn=/^\+[1-9]\d{6,14}$/,Tn=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,ze=100;let re=[],He=!1;function Pn(){typeof navigator<"u"&&navigator.serviceWorker&&navigator.serviceWorker.addEventListener("message",e=>{const t=e.data;(t==null?void 0:t.type)==="arsel_iam_sync"&&Rt()}),typeof window<"u"&&(window.addEventListener("online",()=>{W().catch(()=>{}),ne().catch(()=>{})}),window.addEventListener("pagehide",()=>{fe(),ne().catch(()=>{})})),typeof document<"u"&&document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="visible"){W().catch(()=>{}),ee().catch(()=>{});return}fe(),ne().catch(()=>{})})}function B(){return U===null}function Dn(e){var n,i;if(!((n=e.clientKey)!=null&&n.trim()))return"clientKey is required (the org's publishable pub_… key)";if(!e.clientKey.startsWith("pub_"))return"clientKey should be the publishable pub_… key — never a secret API key";const t=/^http:\/\/(localhost|127\.0\.0\.1)(:\d+)?(\/|$)/.test(e.baseUrl??"");if(!((i=e.baseUrl)!=null&&i.startsWith("https://"))&&!t)return"baseUrl must be HTTPS (http is allowed for localhost only)";try{new URL(e.baseUrl)}catch{return"baseUrl is not a valid URL"}return null}function qe(e){return h||(h=(async()=>{if(ge=e.debug??!1,U=Dn(e),U){console.error(`[arsel] not started — ${U}`);return}const t=e.baseUrl.replace(/\/+$/,"");await Promise.all([u(o.clientKey,e.clientKey),u(o.baseUrl,t)]),await L();const n=re;re=[];for(const a of n)await P(a.name,a.properties,a.timestampMs);e.serviceWorker==="external"?yn():e.serviceWorkerPath&&await bn(e.serviceWorkerPath);const i=On(e.inApp);xn(i?Re:void 0),Pn();const r=typeof document<"u"?document:void 0,s=(r==null?void 0:r.visibilityState)==="visible"&&r.prerendering!==!0;s&&await We(),i&&(Pt(Mn(i)),await In()&&(await Tt(ge),s&&Re())),W().catch(()=>{}),An().catch(()=>{}),E(`initialized (sdk ${V})`)})(),h)}async function we(e,t={}){const n=e==null?void 0:e.trim();if(!n){E("track() called with a blank event name — ignoring");return}if(n.startsWith(T)){E(`'${T}' is reserved for the SDK — ignoring '${n}'`);return}if(!h){if(re.length>=ze){He||(He=!0,console.warn(`[arsel] more than ${ze} events tracked before init() — dropping the rest. Call init() earlier.`));return}re.push({name:n,properties:t,timestampMs:Date.now()});return}await h,B()&&(await P(n,t),de("CUSTOM_EVENT",n,t))}async function Ye(e,t={}){const n=e==null?void 0:e.trim();if(!n){E("screen() called with a blank name — ignoring");return}await h,await P(mt,{...t,screen_name:n}),de("SCREEN_VIEW",n,t)}function Je(e){Dt(e)}async function Ge(e){if(await h,!B())return;let{email:t,phoneNumber:n}=e??{};const i=e==null?void 0:e.externalId;if(t&&!Tn.test(t)&&(console.error(`[arsel] identify(): '${t}' is not a valid email address — ignored`),t=void 0),n&&!kn.test(n)&&(console.error(`[arsel] identify(): '${n}' is not E.164 (e.g. +966501234567) — ignored`),n=void 0),!i&&!t&&!n){E("identify() needs at least one of externalId, email or phoneNumber");return}i&&await u(o.externalId,i),t&&await u(o.email,t),n&&await u(o.phoneNumber,n),await P(pt,{}),await Pe()}async function Ze(){await h,B()&&(await Promise.all([K(o.externalId),K(o.email),K(o.phoneNumber),K(o.sessionStartedAt)]),await lt(),await Pe(),E("identity reset"))}async function Qe(){if(await h,!B())return!1;const e=await Sn();return E(e?"push opt-out recorded":"push opt-out not sent — no registration to revoke"),e}async function et(){if(await h,!B()||!M())return!1;const e=await wn();if(e)return console.error(`[arsel] promptForPush(): ${e}`),!1;const t=await Notification.requestPermission();return t!=="granted"?(E(`notification permission: ${t}`),!1):vn()}async function tt(){return await h,L()}async function nt(){const[e,t,n,i,r,s,a,l,w,f,I,q,_]=await Promise.all([c(o.anonymousId),c(o.externalId),c(o.email),c(o.phoneNumber),c(o.installationId),c(o.deviceSecret),c(o.vapidKeyVersion),Se(v.events),En(),c(o.subscriptionStatus),c(o.lastResponseCode),c(o.lastResponsePath),c(o.lastResponseAtMs)]),C=Ot(),ot=await Mt().catch(()=>0);return{sdkVersion:V,initialized:h!==null&&U===null,configError:U,inAppMessages:C.messages,inAppBundleVersion:C.bundleVersion,inAppFetchedAtMs:C.fetchedAtMs,pendingInAppBeacons:ot,anonymousId:e,hasAssertedIdentity:!!(t||n||i),installationId:r,hasDeviceSecret:!!s,pendingEvents:l,permission:M()?Notification.permission:"unsupported",isSubscribed:w,subscriptionStatus:f,vapidKeyVersion:a,lastResponseCode:I,lastResponsePath:q,lastResponseAtMs:_}}async function it(){await h,B()&&await W()}const rt={init:qe,track:we,screen:Ye,suppressInAppMessages:Je,identify:Ge,reset:Ze,optOut:Qe,promptForPush:et,getAnonymousId:tt,diagnostics:nt,flushNow:it,SDK_VERSION:V};function On(e){if(e===!1)return;const t=typeof e=="object"&&e!==null?e:{};return{zIndex:t.zIndex??Rn,closeLabel:t.closeLabel??"Close"}}function Mn(e){return t=>{const n=Ft();try{en(t,e,{onImpression:()=>void jt(t,n),onButton:i=>{Wt(t,i.buttonId),i.action==="CUSTOM_EVENT"&&i.value&&we(i.value)},onDismiss:i=>{Xt(t,i),Ue()}})}catch(i){E(`in-app render failed: ${i instanceof Error?i.message:""}`),Ue()}}}const Rn=2147483e3;m.Arsel=rt,m.SDK_VERSION=V,m.default=rt,m.diagnostics=nt,m.flushNow=it,m.getAnonymousId=tt,m.identify=Ge,m.init=qe,m.optOut=Qe,m.promptForPush=et,m.reset=Ze,m.screen=Ye,m.suppressInAppMessages=Je,m.track=we,Object.defineProperties(m,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|
|
2
108
|
//# sourceMappingURL=arsel.umd.cjs.map
|