customerio-gist-web 3.15.7 → 3.16.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/gist.min.js +1 -1
- package/package.json +1 -1
- package/src/gist.js +2 -1
- package/src/managers/message-manager.js +3 -2
- package/src/managers/queue-manager.js +83 -8
- package/src/managers/user-manager.js +12 -0
- package/src/services/network.js +3 -3
- package/src/services/queue-service.js +17 -1
- package/src/services/settings.js +20 -0
package/dist/gist.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Gist=t():e.Gist=t()}(this,(()=>(()=>{var e={548:(e,t,n)=>{"use strict";n.d(t,{A:()=>Ie});class s{on(e,t){var n=this[e];n?n.push(t):this[e]=[t]}dispatch(e,t){var n=this[e];n&&n.forEach((e=>e(t)))}}function i(e){Ie.config.logging&&console.log(`Gist: ${e}`)}var a,o=new Uint8Array(16);function r(){if(!a&&!(a="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return a(o)}const u=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;for(var c=[],d=0;d<256;++d)c.push((d+256).toString(16).substr(1));const g=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=(c[e[t+0]]+c[e[t+1]]+c[e[t+2]]+c[e[t+3]]+"-"+c[e[t+4]]+c[e[t+5]]+"-"+c[e[t+6]]+c[e[t+7]]+"-"+c[e[t+8]]+c[e[t+9]]+"-"+c[e[t+10]]+c[e[t+11]]+c[e[t+12]]+c[e[t+13]]+c[e[t+14]]+c[e[t+15]]).toLowerCase();if(!function(e){return"string"==typeof e&&u.test(e)}(n))throw TypeError("Stringified UUID is invalid");return n},l=function(e,t,n){var s=(e=e||{}).random||(e.rng||r)();if(s[6]=15&s[6]|64,s[8]=63&s[8]|128,t){n=n||0;for(var i=0;i<16;++i)t[n+i]=s[i];return t}return g(s)},m=365,f="gist.web.isPersistingSession";function h(e,t,n=null){var s=n;s||(s=new Date).setDate(s.getDate()+m);const i={value:t,expiry:s};y().setItem(e,JSON.stringify(i))}function p(e){const t=y().getItem(e);if(!t)return null;const n=JSON.parse(t);return(new Date).getTime()>new Date(n.expiry).getTime()?(w(e),null):n.value}function w(e){y().removeItem(e)}function v(){const e=sessionStorage.getItem(f);return null===e?(sessionStorage.setItem(f,"true"),!0):"true"===e}function y(){return v()?localStorage:sessionStorage}const b="gist.web.userQueueVersion",I={RENDERER_HOST:"https://code.gist.build",ENGINE_API_ENDPOINT:{prod:"https://engine.api.gist.build",dev:"https://engine.api.dev.gist.build",local:"http://engine.api.local.gist.build:82"},GIST_QUEUE_API_ENDPOINT:{prod:"https://gist-queue-consumer-api.cloud.gist.build",dev:"https://gist-queue-consumer-api.cloud.dev.gist.build",local:"http://api.local.gist.build:86"},GIST_QUEUE_V3_API_ENDPOINT:{prod:"https://consumer.cloud.gist.build",dev:"https://consumer.cloud.dev.gist.build",local:"http://api.local.gist.build:86"},GIST_VIEW_ENDPOINT:{prod:"https://renderer.gist.build/3.0",dev:"https://renderer.gist.build/3.0",local:"http://app.local.gist.build:8080/web"},getQueueAPIVersion:function(){return p(b)??"2"},setQueueAPIVersion:function(e){h(b,e,new Date((new Date).getTime()+18e5)),i(`Set user queue version to "${e}"`)}};function $(){const e="3"===I.getQueueAPIVersion()?I.GIST_QUEUE_V3_API_ENDPOINT[Ie.config.env]:I.GIST_QUEUE_API_ENDPOINT[Ie.config.env],t={"X-CIO-Site-Id":Ie.config.siteId,"X-CIO-Client-Platform":"web"},n=C();async function s(n,s={}){const i=e+n,a=new AbortController,o=setTimeout((()=>a.abort()),5e3);try{const e=await fetch(i,{method:s.method||"GET",headers:{...t,...s.headers||{}},body:s.method&&"GET"!==s.method.toUpperCase()?s.body:void 0,signal:a.signal});clearTimeout(o);const n=e.headers.get("content-type")?.includes("application/json"),r=n?await e.json():await e.text(),u=Object.fromEntries(e.headers.entries());if(e.status<200||e.status>=400)throw{response:{status:e.status,data:r,headers:u}};return{status:e.status,headers:u,data:r}}catch(e){throw clearTimeout(o),e.response||(e.response={status:0,data:e.message||"Unknown error"}),e}}return null!=n&&(t["X-Gist-Encoded-User-Token"]=btoa(n)),s.post=(e,t={},n={})=>s(e,{method:"POST",body:JSON.stringify(t),headers:{"Content-Type":"application/json",...n.headers||{}}}),s}const x="gist.web.userLocale";var S=600,E=!1;const T="gist.web.userQueueNextPullCheck",D="gist.web.sessionId";const k="gist.web.userToken",P="gist.web.usingGuestUserToken",q="gist.web.guestUserToken";function R(){return null!==p(P)}function C(){return p(k)}function M(){if(null===C()){var e=p(q);null==e&&(e=l(),h(q,e),i(`Set guest user token "${e}" with expiry date set to 1 year from today`)),h(k,e),h(P,!0),i(`Using anonymous session with token: "${e}"`)}}async function L(){var e=C();return null===e?null:await async function(e){const t=(new TextEncoder).encode(e),n=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(n)).map((e=>e.toString(16).padStart(2,"0"))).join("")}(e)}function N(e){const t={isEmbedded:!1,elementId:"",hasRouteRule:!1,routeRule:"",position:"",hasPosition:!1,shouldScale:!1,campaignId:null,messageWidth:414,overlayColor:"#00000033",persistent:!1,exitClick:!1,hasCustomWidth:!1},n=e?.properties?.gist;return n?{isEmbedded:!!n.elementId,elementId:n.elementId||"",hasRouteRule:!!n.routeRuleWeb,routeRule:n.routeRuleWeb||"",position:n.position||"",hasPosition:!!n.position,shouldScale:!!n.scale,campaignId:n.campaignId??null,messageWidth:n.messageWidth>0?n.messageWidth:t.messageWidth,hasCustomWidth:n.messageWidth>0,overlayColor:n.overlayColor||t.overlayColor,persistent:!!n.persistent,exitClick:!!n.exitClick}:t}var A=["x-gist-top","x-gist-floating-top","x-gist-bottom","x-gist-floating-bottom","x-gist-floating-bottom-left","x-gist-floating-bottom-right","x-gist-floating-top-left","x-gist-floating-top-right"];const U=e=>new Promise((t=>setTimeout(t,e))),W=["x-gist-top","x-gist-bottom","x-gist-floating-top","x-gist-floating-bottom"];function O(e){var t=H(e);if(t)return t.style&&t.style.height&&"0px"!=t.style.height}function _(e,t){const n=document.getElementById(e);n&&(n.onload=function(){!function(e,t){const n=document.getElementById(e);n&&n.contentWindow&&n.contentWindow.postMessage({options:t},"*")}(e,t)})}function V(){var e=document.querySelector("#gist-embed-message");e&&e.parentNode.removeChild(e)}function G(e){return`gist-${e}`}function j(){var e=document.querySelector(".gist-message");e&&e.classList.add("visible")}function H(e){try{return document.querySelector(`#${e}`)||null}catch{return null}}const Q="gist.web.message.broadcasts";async function z(e,t){return p(e).find((e=>e.queueId===t))}function X(e){return e.properties&&e.properties.gist&&e.properties.gist.broadcast}async function B(){const e=await L();return e?`${Q}.${e}`:null}function J(e,t){return`${e}.${t}.numberOfTimesShown`}function F(e,t){return`${e}.${t}.shouldShow`}const Y="gist.web.message.user";async function K(){const e=await L();return e?`${Y}.${e}`:null}async function Z(){const e=await L();return e?`${Y}.${e}.seen`:null}async function ee(e){const t=await L();return t?`${Y}.${t}.message.${e}.loading`:null}async function te(e){if(Ie.isDocumentVisible){if(Ie.overlayInstanceId)return i(`Message ${Ie.overlayInstanceId} already showing.`),null;var t=N(e);return e.instanceId=l(),e.overlay=!0,e.firstLoad=!0,e.shouldResizeHeight=!0,e.shouldScale=t.shouldScale,e.renderStartTime=(new Date).getTime(),Ie.overlayInstanceId=e.instanceId,Ie.currentMessages.push(e),re(e)}return i("Document hidden, not showing message now."),null}async function ne(e,t){return Ie.isDocumentVisible?(e.instanceId=l(),e.overlay=!1,e.firstLoad=!0,e.shouldScale=!1,e.elementId=t,e.shouldResizeHeight=!O(t),e.renderStartTime=(new Date).getTime(),Ie.currentMessages.push(e),re(e,t)):(i("Document hidden, not showing message now."),null)}async function se(e){e?(Ie.messageDismissed(e),e.overlay?await oe(!0,e):ae(e)):i(`Message with instance id: ${e.instanceId} not found`)}async function ie(e){var t=N(e);e?t.persistent&&(i("Persistent message dismissed, logging view"),await fe(e),await ue(e)):i(`Message with instance id: ${e.instanceId} not found`)}function ae(e){var t;de(e.instanceId),(t=H(e.elementId))&&(t.classList.remove("gist-visible"),t.style.removeProperty("height"),t.innerHTML="")}async function oe(e,t){de(t.instanceId),Ie.overlayInstanceId=null,e?await async function(){var e=document.querySelector(".gist-message");e&&(e.classList.remove("visible"),await U(300)),V()}():V(),0==Ie.currentMessages.length&&(window.removeEventListener("message",me),window.removeEventListener("touchstart",le))}function re(e,t=null){if(t&&function(e){var t=H(e);return!(!t||!t.classList.contains("gist-visible"))}(t))return i(`Message ${e.messageId} already showing in element ${t}.`),null;var n={endpoint:I.ENGINE_API_ENDPOINT[Ie.config.env],siteId:Ie.config.siteId,dataCenter:Ie.config.dataCenter,messageId:e.messageId,instanceId:e.instanceId,livePreview:!1,properties:e.properties},s=`${I.GIST_VIEW_ENDPOINT[Ie.config.env]}/index.html`;return window.addEventListener("message",me),window.addEventListener("touchstart",le),t?(A.includes(t)&&function(e){const t=document.createElement("div");t.id=e,"x-gist-top"===e?document.body.insertBefore(t,document.body.firstChild):document.body.insertAdjacentElement("beforeend",t),i("Top & bottom elements injected into page")}(t),function(e,t,n,s){var a=H(e);if(a){var o=G(n.instanceId);a.classList.add(o);var r=N(n),u=r.messageWidth+"px";W.includes(e)&&!r.hasCustomWidth&&(u="100%"),A.includes(e)&&(a.style.width=u),O(e)||(a.style.height="0px"),a.innerHTML=function(e,t,n){var s=function(e,t,n){var s=800;return t.messageWidth>s&&(s=t.messageWidth),`\n <div id="gist-embed">\n <style>\n #x-gist-floating-top, #x-gist-floating-top-left, #x-gist-floating-top-right {\n position: fixed;\n top: 0px;\n z-index: 1000000;\n }\n #x-gist-floating-bottom, #x-gist-floating-bottom-left, #x-gist-floating-bottom-right {\n position: fixed;\n bottom: 0px;\n z-index: 1000000;\n }\n #x-gist-bottom, #x-gist-top, #x-gist-floating-top, #x-gist-floating-bottom {\n left: 50%;\n transform: translate(-50%, 0%);\n }\n #x-gist-floating-top-right, #x-gist-floating-bottom-right {\n right: 0px;\n }\n #gist-embed {\n position: relative;\n height: 100%;\n width: 100%;\n }\n #gist-embed-container {\n position: relative;\n height: 100%;\n width: 100%;\n }\n #gist-embed-container .gist-frame {\n height: 100%;\n width: 100%;\n border: none;\n }\n #x-gist-top.${e},\n #x-gist-bottom.${e},\n #x-gist-floating-top.${e},\n #x-gist-floating-bottom.${e},\n #x-gist-floating-top-left.${e},\n #x-gist-floating-top-right.${e},\n #x-gist-floating-bottom-left.${e},\n #x-gist-floating-bottom-right.${e} {\n transition: height 0.1s ease-in-out;\n }\n @media (max-width: ${s}px) {\n #x-gist-top.${e},\n #x-gist-bottom.${e},\n #x-gist-floating-top.${e},\n #x-gist-floating-bottom.${e},\n #x-gist-floating-top-left.${e},\n #x-gist-floating-top-right.${e},\n #x-gist-floating-bottom-left.${e},\n #x-gist-floating-bottom-right.${e} {\n width: 100% !important;\n }\n }\n </style>\n <div id="gist-embed-container">\n <iframe id="${e}" class="gist-frame" src="${n}"></iframe>\n </div>\n </div>`}(G(t.instanceId),n,e);return s}(t,n,r),_(o,s)}else i(`Message could not be embedded, elementId ${e} not found.`)}(t,s,e,n)):function(e,t,n){document.body.insertAdjacentHTML("afterbegin",function(e,t){var n=N(t),s=function(e,t,n){var s=600;return t.messageWidth>s&&(s=t.messageWidth),`\n <div id="gist-embed-message">\n <style>\n #gist-overlay.background {\n position: fixed;\n z-index: 9999999998;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n background-color: ${t.overlayColor};\n visibility: hidden;\n }\n #gist-overlay.background.visible {\n visibility: visible;\n }\n #gist-overlay.background.is-blacked-out {\n display: block;\n }\n .gist-message {\n width: ${t.messageWidth}px;\n position: absolute;\n border: none;\n opacity: 0;\n transition: opacity 0.3s ease-in-out, height 0.1s ease-in-out;\n z-index: 9999999999;\n left: 50%;\n transform: translateX(-50%);\n }\n .gist-message.visible {\n opacity: 1;\n pointer-events: auto;\n }\n .gist-message.center {\n transform: translate(-50%, -50%);\n top: 50%;\n }\n .gist-message.bottom {\n bottom: 0;\n }\n .gist-message.top {\n top: 0;\n }\n @media (max-width: ${s}px) {\n .gist-message {\n width: 100%;\n }\n }\n </style>\n <div id="gist-overlay" class="background">\n <iframe id="${e}" class="gist-message" src="${n}"></iframe>\n </div>\n </div>`}(G(t.instanceId),n,e);return s}(e,t)),_(G(t.instanceId),n)}(s,e,n),e}async function ue(e){i(`Message shown, logging view for: ${e.messageId}`);var t={};null!=e.queueId?(await fe(e),t=await async function(e){try{return await $().post(`/api/v1/logs/queue/${e}`)}catch(e){return e.response}}(e.queueId)):t=await async function(e){try{return await $().post(`/api/v1/logs/message/${e}`)}catch(e){return e.response}}(e.messageId),200===t.status?i("Message view logged"):i(`Problem logging message: ${t.status}`)}function ce(e){return Ie.currentMessages.find((t=>t.instanceId===e))}function de(e){Ie.currentMessages=Ie.currentMessages.filter((t=>t.instanceId!==e))}function ge(e,t){de(e),Ie.currentMessages.push(t)}function le(){}async function me(e){if(e.data.gist&&e.origin===I.RENDERER_HOST){var t=e.data.gist.instanceId,n=ce(t);if(!n)return;var s=N(n);switch(e.data.gist.method){case"routeLoaded":var a=.001*((new Date).getTime()-n.renderStartTime);i(`Engine render for message: ${n.messageId} timer elapsed in ${a.toFixed(3)} seconds`),async function(e){const t=await ee(e);if(!t)return!1;w(t)}(n.queueId),n.currentRoute=e.data.gist.parameters.route,n.firstLoad&&(n.overlay?function(e){var t=N(e),n=document.querySelector("#gist-overlay");if(n){n.classList.add("visible");var s=document.querySelector(".gist-message");e.position?s.classList.add(e.position):s.classList.add("center"),setTimeout(j,100),t.exitClick&&setTimeout((()=>function(e){var t=document.querySelector("#gist-overlay");t&&t.addEventListener("click",(function(){Ie.dismissMessage(e)}))}(e.instanceId)),1e3)}else V()}(n):(g=H(n.elementId))&&g.classList.add("gist-visible"),Ie.messageShown(n),s.persistent?i("Persistent message shown, skipping logging view"):await ue(n),n.firstLoad=!1),ge(t,n);break;case"tap":var o=e.data.gist.parameters.action,r=e.data.gist.parameters.name;if(Ie.messageAction(n,o,r),e.data.gist.parameters.system&&!s.persistent){await se(n);break}try{var u=new URL(o);if(u&&"gist:"===u.protocol)switch(u.href.replace("gist://","").split("?")[0]){case"close":await se(n),await ie(n),await he(n),await ye();break;case"showMessage":var c=u.searchParams.get("messageId"),d=u.searchParams.get("properties");c&&(d&&(d=JSON.parse(atob(d))),await Ie.showMessage({messageId:c,properties:d}));break;case"loadPage":(u=u.href.substring(u.href.indexOf("?url=")+5))&&(u.startsWith("mailto:")||u.startsWith("https://")||u.startsWith("http://")||u.startsWith("/")?window.location.href=u:window.location.href=window.location+u)}}catch{}break;case"routeChanged":n.currentRoute=e.data.gist.parameters.route,n.renderStartTime=(new Date).getTime(),ge(t,n),i(`Route changed to: ${n.currentRoute}`);break;case"sizeChanged":i(`Size Changed Width: ${e.data.gist.parameters.width} - Height: ${e.data.gist.parameters.height}`),n.elementId&&!n.shouldResizeHeight||function(e,t){var n=H(e.elementId?e.elementId:G(e.instanceId));if(n){var s=n.style;if(t.height>0)if(t.height>window.innerHeight){var i=1-(t.height/window.innerHeight-1);e.shouldScale&&i>=.4?(s.height=`${t.height}px`,s.transform=`translateX(-50%) translateY(-50%) scale(${i})`):s.height=`${window.innerHeight}px`}else s.height=`${t.height}px`}}(n,e.data.gist.parameters);break;case"titleChanged":i(`Overlay title changed to: ${e.data.gist.parameters.title}`),function(e,t){var n=H(G(e));n&&(n.title=t)}(t,e.data.gist.parameters.title);break;case"eventDispatched":Ie.events.dispatch("eventDispatched",{name:e.data.gist.parameters.name,payload:e.data.gist.parameters.payload});break;case"error":case"routeError":Ie.messageError(n),Ie.overlayInstanceId?oe(!1,n):ae(n)}}var g}async function fe(e){i(`Logging user message view locally for: ${e.queueId}`),X(e)?await async function(e){i(`Marking broadcast ${e} as seen.`);const t=await B();if(!t)return;const n=await z(t,e);if(!n)return;const{broadcast:s}=n.properties.gist,a=J(t,e),o=F(t,e);let r=p(a)||0;if(h(a,r+1),1===s.frequency.count)h(o,!1),i(`Marked broadcast ${e} as seen.`);else{let t=new Date;t.setSeconds(t.getSeconds()+s.frequency.delay),h(o,!1,t),i(`Marked broadcast ${e} as seen, broadcast was seen ${r+1} times, next show date is ${t}.`)}}(e.queueId):await async function(e){const t=await Z();if(!t)return;const n=p(t)??[];n.push(e),h(t,n)}(e.queueId)}async function he(e){X(e)&&(i(`Logging broadcast dismissed locally for: ${e.queueId}`),await async function(e){i(`Marking broadcast ${e} as dismissed.`);const t=await B();if(!t)return;const n=await z(t,e);if(!n)return;const{broadcast:s}=n.properties.gist;!0!==s.frequency.ignoreDismiss?(h(F(t,e),!1),i(`Marked broadcast ${e} as dismissed and will not show again.`)):i(`Broadcast ${e} is set to ignore dismiss.`)}(e.queueId))}var pe=(e,t)=>e().then((e=>new Promise((t=>setTimeout(t,e))))(t).then((()=>pe(e,t)))),we=!1;async function ve(){we?ye():C()?(i("Queue watcher started"),we=!0,pe((()=>new Promise((()=>async function(){if(C())if(Ie.isDocumentVisible)if(null===p(T)){var e=await async function(){var e,t;try{if(!E){E=!0;var n={"X-Gist-User-Anonymous":R(),"Content-Language":null!==p(x)?p(x):navigator.language};if("3"===I.getQueueAPIVersion())e=await $().post(`/api/v3/users?sessionId=${t=p(D),t||(t=l()),h(D,t,new Date((new Date).getTime()+18e5)),t}`,{},{headers:n});else{var s=(new Date).getTime();e=await $().post(`/api/v2/users?timestamp=${s}`,{},{headers:n})}}}catch(t){t.response?e=t.response:i(`Error getting user queue: ${t}`)}finally{E=!1,function(e){if(e&&e.headers){var t=e.headers["x-gist-queue-polling-interval"];t&&t>0&&(S=t)}var n=new Date((new Date).getTime()+1e3*S);h(T,S,n)}(e),function(e){if(e&&e.headers){var t=e.headers["x-cio-queue-version"];t&&I.setQueueAPIVersion(t)}}(e)}return e}(),t=[];e?(200===e.status||204===e.status?(i("200 response, updating local store."),async function(e){const t=await K();t&&h(t,e.filter((e=>!(e.properties&&e.properties.gist&&e.properties.gist.broadcast))),new Date(Date.now()+36e5))}(t=e.data),async function(e){const t=await B();if(!t)return;const n=new Date;n.setDate(n.getDate()+30),h(t,e.filter(X),n)}(t)):304===e.status&&i("304 response, using local store."),await ye()):i("There was an error while checking message queue.")}else i("Next queue pull scheduled for later.");else i("Document not visible, skipping queue check.");else i("User token reset, skipping queue check.")}()))),1e3)):i("User token not setup, queue not started.")}async function ye(){var e=await async function(){const e=await B();return e?(p(e)??[]).filter((t=>{const{broadcast:n}=t.properties.gist,s=p(F(e,t.queueId))??!0,i=p(J(e,t.queueId))||0,a=0===n.frequency.count;return s&&(a||i<n.frequency.count)})):[]}(),t=await async function(){const e=await K();if(!e)return[];const t=p(e)??[],n=await async function(){const e=await Z();return e?p(e)??[]:[]}();return t.filter((e=>!n.includes(e.queueId)))}(),n=e.concat(t);i(`Messages in local queue: ${n.length}`);var s=n.sort(((e,t)=>e.priority-t.priority));for(const e of s)await be(e)}async function be(e){var t=N(e);if(t.hasRouteRule){var n=Ie.currentRoute;null==n&&(n=new URL(window.location.href).pathname);var s=t.routeRule;if(i(`Verifying route against rule: ${s}`),!new RegExp(s).test(n))return i(`Route ${n} does not match rule.`),!1}if(t.hasPosition&&(e.position=t.position),t.persistent||function(e){if(!X(e))return!1;const{broadcast:t}=e.properties.gist;return 0===t.frequency.delay&&0===t.frequency.count}(e)||!await async function(e){const t=await ee(e);return!!t&&null!==p(t)}(e.queueId)){var a;return(a=t.isEmbedded?await ne(e,t.elementId):await te(e))&&async function(e){const t=await ee(e);if(!t)return!1;h(t,!0,new Date(Date.now()+5e3))}(e.queueId),a}return i(`Not showing message with queueId ${e.queueId} because its already loading.`),!1}const Ie=class{static async setup(e){this.events=new s,this.config={useAnonymousSession:void 0!==e.useAnonymousSession&&e.useAnonymousSession,siteId:e.siteId,dataCenter:e.dataCenter,env:void 0===e.env?"prod":e.env,logging:void 0!==e.logging&&e.logging,experiments:void 0!==e.experiments&&e.experiments},this.currentMessages=[],this.overlayInstanceId=null,this.currentRoute=null,this.isDocumentVisible=!0,this.config.isPreviewSession=function(){const e=new URLSearchParams(window.location.search).get("cioPreviewId");return e&&(sessionStorage.setItem(f,!1),Ie.setUserToken(e),i(`Preview mode enabled with user token: ${e}`)),!v()}(),i(`Setup complete on ${this.config.env} environment.`),!this.config.isPreviewSession&&this.config.useAnonymousSession&&M(),await ve(),document.addEventListener("visibilitychange",(async()=>{"hidden"===document.visibilityState?this.isDocumentVisible=!1:(this.isDocumentVisible=!0,await ye())}),!1)}static async setCurrentRoute(e){this.currentRoute=e,i(`Current route set to: ${e}`),await ye()}static async setUserToken(e,t){this.config.isPreviewSession||(function(e,t){void 0===t&&(t=new Date).setDate(t.getDate()+30),h(k,e,t),R()&&(w(T),w(P)),i(`Set user token "${e}" with expiry date set to ${t}`)}(e,t),await ve())}static setUserLocale(e){var t;h(x,t=e),i(`Set user locate to "${t}"`)}static async clearUserToken(){this.config.isPreviewSession||(w(k),i("Cleared user token"),this.config.useAnonymousSession&&M(),await ve())}static async dismissMessage(e){var t=ce(e);await se(t),await ie(t),await he(t),await ye()}static async embedMessage(e,t){var n=await ne(e,t);return n?n.instanceId:null}static async showMessage(e){var t=await te(e);return t?t.instanceId:null}static messageShown(e){i(`Message shown: ${e.messageId}`),this.events.dispatch("messageShown",e)}static messageDismissed(e){null!==e&&(i(`Message dismissed: ${e.messageId}`),this.events.dispatch("messageDismissed",e))}static messageError(e){i(`Message error: ${e.messageId}`),this.events.dispatch("messageError",e)}static messageAction(e,t,n){i(`Message action: ${e.currentRoute}, ${t} with name ${n} on ${e.instanceId}`),this.events.dispatch("messageAction",{message:e,action:t,name:n})}}},44:(e,t,n)=>{const s=n(548).A;e.exports=s}},t={};function n(s){var i=t[s];if(void 0!==i)return i.exports;var a=t[s]={exports:{}};return e[s](a,a.exports,n),a.exports}return n.d=(e,t)=>{for(var s in t)n.o(t,s)&&!n.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n(44)})()));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Gist=t():e.Gist=t()}(this,(()=>(()=>{var e={548:(e,t,n)=>{"use strict";n.d(t,{A:()=>Re});class s{on(e,t){var n=this[e];n?n.push(t):this[e]=[t]}dispatch(e,t){var n=this[e];n&&n.forEach((e=>e(t)))}}function i(e){Re.config.logging&&console.log(`Gist: ${e}`)}var a,o=new Uint8Array(16);function r(){if(!a&&!(a="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return a(o)}const u=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;for(var c=[],d=0;d<256;++d)c.push((d+256).toString(16).substr(1));const g=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=(c[e[t+0]]+c[e[t+1]]+c[e[t+2]]+c[e[t+3]]+"-"+c[e[t+4]]+c[e[t+5]]+"-"+c[e[t+6]]+c[e[t+7]]+"-"+c[e[t+8]]+c[e[t+9]]+"-"+c[e[t+10]]+c[e[t+11]]+c[e[t+12]]+c[e[t+13]]+c[e[t+14]]+c[e[t+15]]).toLowerCase();if(!function(e){return"string"==typeof e&&u.test(e)}(n))throw TypeError("Stringified UUID is invalid");return n},l=function(e,t,n){var s=(e=e||{}).random||(e.rng||r)();if(s[6]=15&s[6]|64,s[8]=63&s[8]|128,t){n=n||0;for(var i=0;i<16;++i)t[n+i]=s[i];return t}return g(s)},m=365,f="gist.web.isPersistingSession";function h(e,t,n=null){var s=n;s||(s=new Date).setDate(s.getDate()+m);const i={value:t,expiry:s};y().setItem(e,JSON.stringify(i))}function p(e){const t=y().getItem(e);if(!t)return null;const n=JSON.parse(t);return(new Date).getTime()>new Date(n.expiry).getTime()?(w(e),null):n.value}function w(e){y().removeItem(e)}function v(){const e=sessionStorage.getItem(f);return null===e?(sessionStorage.setItem(f,"true"),!0):"true"===e}function y(){return v()?localStorage:sessionStorage}const b="gist.web.userQueueVersion",I="gist.web.userQueueUseSSE",S="gist.web.activeSSEConnection",$={RENDERER_HOST:"https://code.gist.build",ENGINE_API_ENDPOINT:{prod:"https://engine.api.gist.build",dev:"https://engine.api.dev.gist.build",local:"http://engine.api.local.gist.build:82"},GIST_QUEUE_API_ENDPOINT:{prod:"https://gist-queue-consumer-api.cloud.gist.build",dev:"https://gist-queue-consumer-api.cloud.dev.gist.build",local:"http://api.local.gist.build:86"},GIST_QUEUE_V3_API_ENDPOINT:{prod:"https://consumer.cloud.gist.build",dev:"https://consumer.cloud.dev.gist.build",local:"http://api.local.gist.build:86"},GIST_QUEUE_REALTIME_API_ENDPOINT:{prod:"https://realtime.cloud.gist.build",dev:"https://realtime.cloud.dev.gist.build",local:"http://api.local.gist.build:3000"},GIST_VIEW_ENDPOINT:{prod:"https://renderer.gist.build/3.0",dev:"https://renderer.gist.build/3.0",local:"http://app.local.gist.build:8080/web"},getQueueAPIVersion:function(){return p(b)??"2"},setQueueAPIVersion:function(e){h(b,e,new Date((new Date).getTime()+18e5)),i(`Set user queue version to "${e}"`)},useSSE:function(){return p(I)??!1},setUseSSEFlag:function(e){h(I,e,new Date((new Date).getTime()+6e4)),i(`Set user uses SSE to "${e}"`)},setActiveSSEConnection:function(){h(S,!0,new Date((new Date).getTime()+31e3))},hasActiveSSEConnection:function(){return p(S)??!1}};function E(){const e="3"===$.getQueueAPIVersion()?$.GIST_QUEUE_V3_API_ENDPOINT[Re.config.env]:$.GIST_QUEUE_API_ENDPOINT[Re.config.env],t={"X-CIO-Site-Id":Re.config.siteId,"X-CIO-Client-Platform":"web"},n=_();async function s(n,s={}){const i=e+n,a=new AbortController,o=setTimeout((()=>a.abort()),5e3);try{const e=await fetch(i,{method:s.method||"GET",headers:{...t,...s.headers||{}},body:s.method&&"GET"!==s.method.toUpperCase()?s.body:void 0,signal:a.signal});clearTimeout(o);const n=e.headers.get("content-type")?.includes("application/json"),r=n?await e.json():await e.text(),u=Object.fromEntries(e.headers.entries());if(e.status<200||e.status>=400)throw{response:{status:e.status,data:r,headers:u}};return{status:e.status,headers:u,data:r}}catch(e){throw clearTimeout(o),e.response||(e.response={status:0,data:e.message||"Unknown error"}),e}}return null!=n&&(t["X-Gist-Encoded-User-Token"]=n),s.post=(e,t={},n={})=>s(e,{method:"POST",body:JSON.stringify(t),headers:{"Content-Type":"application/json",...n.headers||{}}}),s}const x="gist.web.userLocale";var T=600,D=!1;const k="gist.web.userQueueNextPullCheck",P="gist.web.sessionId";function C(){var e=p(P);return e||(e=l()),h(P,e,new Date((new Date).getTime()+18e5)),e}const q="gist.web.userToken",R="gist.web.usingGuestUserToken",A="gist.web.guestUserToken";function L(){return null!==p(R)}function U(){return p(q)}function M(){if(null===U()){var e=p(A);null==e&&(e=l(),h(A,e),i(`Set guest user token "${e}" with expiry date set to 1 year from today`)),h(q,e),h(R,!0),i(`Using anonymous session with token: "${e}"`)}}async function N(){var e=U();return null===e?null:await async function(e){const t=(new TextEncoder).encode(e),n=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(n)).map((e=>e.toString(16).padStart(2,"0"))).join("")}(e)}function _(){var e=U();return null===e?null:btoa(e)}function O(e){const t={isEmbedded:!1,elementId:"",hasRouteRule:!1,routeRule:"",position:"",hasPosition:!1,shouldScale:!1,campaignId:null,messageWidth:414,overlayColor:"#00000033",persistent:!1,exitClick:!1,hasCustomWidth:!1},n=e?.properties?.gist;return n?{isEmbedded:!!n.elementId,elementId:n.elementId||"",hasRouteRule:!!n.routeRuleWeb,routeRule:n.routeRuleWeb||"",position:n.position||"",hasPosition:!!n.position,shouldScale:!!n.scale,campaignId:n.campaignId??null,messageWidth:n.messageWidth>0?n.messageWidth:t.messageWidth,hasCustomWidth:n.messageWidth>0,overlayColor:n.overlayColor||t.overlayColor,persistent:!!n.persistent,exitClick:!!n.exitClick}:t}var W=["x-gist-top","x-gist-floating-top","x-gist-bottom","x-gist-floating-bottom","x-gist-floating-bottom-left","x-gist-floating-bottom-right","x-gist-floating-top-left","x-gist-floating-top-right"];const V=e=>new Promise((t=>setTimeout(t,e))),G=["x-gist-top","x-gist-bottom","x-gist-floating-top","x-gist-floating-bottom"];function Q(e){var t=X(e);if(t)return t.style&&t.style.height&&"0px"!=t.style.height}function j(e,t){const n=document.getElementById(e);n&&(n.onload=function(){!function(e,t){const n=document.getElementById(e);n&&n.contentWindow&&n.contentWindow.postMessage({options:t},"*")}(e,t)})}function H(){var e=document.querySelector("#gist-embed-message");e&&e.parentNode.removeChild(e)}function z(e){return`gist-${e}`}function F(){var e=document.querySelector(".gist-message");e&&e.classList.add("visible")}function X(e){try{return document.querySelector(`#${e}`)||null}catch{return null}}const J="gist.web.message.broadcasts",B=30;async function Y(e){const t=await ee();if(!t)return;const n=new Date;n.setDate(n.getDate()+B),h(t,e.filter(Z),n)}async function K(e,t){return p(e).find((e=>e.queueId===t))}function Z(e){return e.properties&&e.properties.gist&&e.properties.gist.broadcast}async function ee(){const e=await N();return e?`${J}.${e}`:null}function te(e,t){return`${e}.${t}.numberOfTimesShown`}function ne(e,t){return`${e}.${t}.shouldShow`}const se="gist.web.message.user",ie=36e5;async function ae(e){const t=await oe();t&&h(t,e.filter((e=>!(e.properties&&e.properties.gist&&e.properties.gist.broadcast))),new Date(Date.now()+ie))}async function oe(){const e=await N();return e?`${se}.${e}`:null}async function re(){const e=await N();return e?`${se}.${e}.seen`:null}async function ue(e){const t=await N();return t?`${se}.${t}.message.${e}.loading`:null}async function ce(e){if(Re.isDocumentVisible){if(Re.overlayInstanceId)return i(`Message ${Re.overlayInstanceId} already showing.`),null;var t=O(e);return e.instanceId=l(),e.overlay=!0,e.firstLoad=!0,e.shouldResizeHeight=!0,e.shouldScale=t.shouldScale,e.renderStartTime=(new Date).getTime(),Re.overlayInstanceId=e.instanceId,Re.currentMessages.push(e),he(e)}return i("Document hidden, not showing message now."),null}async function de(e,t){return Re.isDocumentVisible?(e.instanceId=l(),e.overlay=!1,e.firstLoad=!0,e.shouldScale=!1,e.elementId=t,e.shouldResizeHeight=!Q(t),e.renderStartTime=(new Date).getTime(),Re.currentMessages.push(e),he(e,t)):(i("Document hidden, not showing message now."),null)}async function ge(e){e?(Re.messageDismissed(e),e.overlay?await fe(!0,e):me(e)):i(`Message with instance id: ${e.instanceId} not found`)}async function le(e){var t=O(e);e?t.persistent&&(i("Persistent message dismissed, logging view"),await Se(e),await pe(e)):i(`Message with instance id: ${e.instanceId} not found`)}function me(e){var t;ve(e.instanceId),(t=X(e.elementId))&&(t.classList.remove("gist-visible"),t.style.removeProperty("height"),t.innerHTML="")}async function fe(e,t){e?await async function(){var e=document.querySelector(".gist-message");e&&(e.classList.remove("visible"),await V(300)),H()}():H(),0==Re.currentMessages.length&&(window.removeEventListener("message",Ie),window.removeEventListener("touchstart",be)),ve(t.instanceId),Re.overlayInstanceId=null}function he(e,t=null){if(t&&function(e){var t=X(e);return!(!t||!t.classList.contains("gist-visible"))}(t))return i(`Message ${e.messageId} already showing in element ${t}.`),null;var n={endpoint:$.ENGINE_API_ENDPOINT[Re.config.env],siteId:Re.config.siteId,dataCenter:Re.config.dataCenter,messageId:e.messageId,instanceId:e.instanceId,livePreview:!1,properties:e.properties},s=`${$.GIST_VIEW_ENDPOINT[Re.config.env]}/index.html`;return window.addEventListener("message",Ie),window.addEventListener("touchstart",be),t?(W.includes(t)&&function(e){const t=document.createElement("div");t.id=e,"x-gist-top"===e?document.body.insertBefore(t,document.body.firstChild):document.body.insertAdjacentElement("beforeend",t),i("Top & bottom elements injected into page")}(t),function(e,t,n,s){var a=X(e);if(a){var o=z(n.instanceId);a.classList.add(o);var r=O(n),u=r.messageWidth+"px";G.includes(e)&&!r.hasCustomWidth&&(u="100%"),W.includes(e)&&(a.style.width=u),Q(e)||(a.style.height="0px"),a.innerHTML=function(e,t,n){var s=function(e,t,n){var s=800;return t.messageWidth>s&&(s=t.messageWidth),`\n <div id="gist-embed">\n <style>\n #x-gist-floating-top, #x-gist-floating-top-left, #x-gist-floating-top-right {\n position: fixed;\n top: 0px;\n z-index: 1000000;\n }\n #x-gist-floating-bottom, #x-gist-floating-bottom-left, #x-gist-floating-bottom-right {\n position: fixed;\n bottom: 0px;\n z-index: 1000000;\n }\n #x-gist-bottom, #x-gist-top, #x-gist-floating-top, #x-gist-floating-bottom {\n left: 50%;\n transform: translate(-50%, 0%);\n }\n #x-gist-floating-top-right, #x-gist-floating-bottom-right {\n right: 0px;\n }\n #gist-embed {\n position: relative;\n height: 100%;\n width: 100%;\n }\n #gist-embed-container {\n position: relative;\n height: 100%;\n width: 100%;\n }\n #gist-embed-container .gist-frame {\n height: 100%;\n width: 100%;\n border: none;\n }\n #x-gist-top.${e},\n #x-gist-bottom.${e},\n #x-gist-floating-top.${e},\n #x-gist-floating-bottom.${e},\n #x-gist-floating-top-left.${e},\n #x-gist-floating-top-right.${e},\n #x-gist-floating-bottom-left.${e},\n #x-gist-floating-bottom-right.${e} {\n transition: height 0.1s ease-in-out;\n }\n @media (max-width: ${s}px) {\n #x-gist-top.${e},\n #x-gist-bottom.${e},\n #x-gist-floating-top.${e},\n #x-gist-floating-bottom.${e},\n #x-gist-floating-top-left.${e},\n #x-gist-floating-top-right.${e},\n #x-gist-floating-bottom-left.${e},\n #x-gist-floating-bottom-right.${e} {\n width: 100% !important;\n }\n }\n </style>\n <div id="gist-embed-container">\n <iframe id="${e}" class="gist-frame" src="${n}"></iframe>\n </div>\n </div>`}(z(t.instanceId),n,e);return s}(t,n,r),j(o,s)}else i(`Message could not be embedded, elementId ${e} not found.`)}(t,s,e,n)):function(e,t,n){document.body.insertAdjacentHTML("afterbegin",function(e,t){var n=O(t),s=function(e,t,n){var s=600;return t.messageWidth>s&&(s=t.messageWidth),`\n <div id="gist-embed-message">\n <style>\n #gist-overlay.background {\n position: fixed;\n z-index: 9999999998;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n background-color: ${t.overlayColor};\n visibility: hidden;\n }\n #gist-overlay.background.visible {\n visibility: visible;\n }\n #gist-overlay.background.is-blacked-out {\n display: block;\n }\n .gist-message {\n width: ${t.messageWidth}px;\n position: absolute;\n border: none;\n opacity: 0;\n transition: opacity 0.3s ease-in-out, height 0.1s ease-in-out;\n z-index: 9999999999;\n left: 50%;\n transform: translateX(-50%);\n }\n .gist-message.visible {\n opacity: 1;\n pointer-events: auto;\n }\n .gist-message.center {\n transform: translate(-50%, -50%);\n top: 50%;\n }\n .gist-message.bottom {\n bottom: 0;\n }\n .gist-message.top {\n top: 0;\n }\n @media (max-width: ${s}px) {\n .gist-message {\n width: 100%;\n }\n }\n </style>\n <div id="gist-overlay" class="background">\n <iframe id="${e}" class="gist-message" src="${n}"></iframe>\n </div>\n </div>`}(z(t.instanceId),n,e);return s}(e,t)),j(z(t.instanceId),n)}(s,e,n),e}async function pe(e){i(`Message shown, logging view for: ${e.messageId}`);var t={};null!=e.queueId?(await Se(e),t=await async function(e){try{return await E().post(`/api/v1/logs/queue/${e}`)}catch(e){return e.response}}(e.queueId)):t=await async function(e){try{return await E().post(`/api/v1/logs/message/${e}`)}catch(e){return e.response}}(e.messageId),200===t.status?i("Message view logged"):i(`Problem logging message: ${t.status}`)}function we(e){return Re.currentMessages.find((t=>t.instanceId===e))}function ve(e){Re.currentMessages=Re.currentMessages.filter((t=>t.instanceId!==e))}function ye(e,t){ve(e),Re.currentMessages.push(t)}function be(){}async function Ie(e){if(e.data.gist&&e.origin===$.RENDERER_HOST){var t=e.data.gist.instanceId,n=we(t);if(!n)return;var s=O(n);switch(e.data.gist.method){case"routeLoaded":var a=.001*((new Date).getTime()-n.renderStartTime);i(`Engine render for message: ${n.messageId} timer elapsed in ${a.toFixed(3)} seconds`),async function(e){const t=await ue(e);if(!t)return!1;w(t)}(n.queueId),n.currentRoute=e.data.gist.parameters.route,n.firstLoad&&(n.overlay?function(e){var t=O(e),n=document.querySelector("#gist-overlay");if(n){n.classList.add("visible");var s=document.querySelector(".gist-message");e.position?s.classList.add(e.position):s.classList.add("center"),setTimeout(F,100),t.exitClick&&setTimeout((()=>function(e){var t=document.querySelector("#gist-overlay");t&&t.addEventListener("click",(function(){Re.dismissMessage(e)}))}(e.instanceId)),1e3)}else H()}(n):(g=X(n.elementId))&&g.classList.add("gist-visible"),Re.messageShown(n),s.persistent?i("Persistent message shown, skipping logging view"):await pe(n),n.firstLoad=!1),ye(t,n);break;case"tap":var o=e.data.gist.parameters.action,r=e.data.gist.parameters.name;if(Re.messageAction(n,o,r),e.data.gist.parameters.system&&!s.persistent){await ge(n);break}try{var u=new URL(o);if(u&&"gist:"===u.protocol)switch(u.href.replace("gist://","").split("?")[0]){case"close":await ge(n),await le(n),await $e(n),await ke();break;case"showMessage":var c=u.searchParams.get("messageId"),d=u.searchParams.get("properties");c&&(d&&(d=JSON.parse(atob(d))),await Re.showMessage({messageId:c,properties:d}));break;case"loadPage":(u=u.href.substring(u.href.indexOf("?url=")+5))&&(u.startsWith("mailto:")||u.startsWith("https://")||u.startsWith("http://")||u.startsWith("/")?window.location.href=u:window.location.href=window.location+u)}}catch{}break;case"routeChanged":n.currentRoute=e.data.gist.parameters.route,n.renderStartTime=(new Date).getTime(),ye(t,n),i(`Route changed to: ${n.currentRoute}`);break;case"sizeChanged":i(`Size Changed Width: ${e.data.gist.parameters.width} - Height: ${e.data.gist.parameters.height}`),n.elementId&&!n.shouldResizeHeight||function(e,t){var n=X(e.elementId?e.elementId:z(e.instanceId));if(n){var s=n.style;if(t.height>0)if(t.height>window.innerHeight){var i=1-(t.height/window.innerHeight-1);e.shouldScale&&i>=.4?(s.height=`${t.height}px`,s.transform=`translateX(-50%) translateY(-50%) scale(${i})`):s.height=`${window.innerHeight}px`}else s.height=`${t.height}px`}}(n,e.data.gist.parameters);break;case"titleChanged":i(`Overlay title changed to: ${e.data.gist.parameters.title}`),function(e,t){var n=X(z(e));n&&(n.title=t)}(t,e.data.gist.parameters.title);break;case"eventDispatched":Re.events.dispatch("eventDispatched",{name:e.data.gist.parameters.name,payload:e.data.gist.parameters.payload});break;case"error":case"routeError":Re.messageError(n),Re.overlayInstanceId?fe(!1,n):me(n)}}var g}async function Se(e){i(`Logging user message view locally for: ${e.queueId}`),Z(e)?await async function(e){i(`Marking broadcast ${e} as seen.`);const t=await ee();if(!t)return;const n=await K(t,e);if(!n)return;const{broadcast:s}=n.properties.gist,a=te(t,e),o=ne(t,e);let r=p(a)||0;if(h(a,r+1),1===s.frequency.count)h(o,!1),i(`Marked broadcast ${e} as seen.`);else{let t=new Date;t.setSeconds(t.getSeconds()+s.frequency.delay),h(o,!1,t),i(`Marked broadcast ${e} as seen, broadcast was seen ${r+1} times, next show date is ${t}.`)}}(e.queueId):await async function(e){const t=await re();if(!t)return;const n=p(t)??[];n.push(e),h(t,n)}(e.queueId)}async function $e(e){Z(e)&&(i(`Logging broadcast dismissed locally for: ${e.queueId}`),await async function(e){i(`Marking broadcast ${e} as dismissed.`);const t=await ee();if(!t)return;const n=await K(t,e);if(!n)return;const{broadcast:s}=n.properties.gist;!0!==s.frequency.ignoreDismiss?(h(ne(t,e),!1),i(`Marked broadcast ${e} as dismissed and will not show again.`)):i(`Broadcast ${e} is set to ignore dismiss.`)}(e.queueId))}var Ee=(e,t)=>e().then((e=>new Promise((t=>setTimeout(t,e))))(t).then((()=>Ee(e,t)))),xe=!1;let Te=null;async function De(){xe?await ke():U()?(i("Queue watcher started"),xe=!0,Ee((()=>new Promise((()=>async function(){$.hasActiveSSEConnection()?await ke():!$.useSSE()||L()?await Ce():await async function(){const e=null===(t=_())?(i("No user token available for SSE endpoint."),null):$.GIST_QUEUE_REALTIME_API_ENDPOINT[Re.config.env]+`/api/v3/sse?userToken=${t}&siteId=${Re.config.siteId}&sessionId=${C()}`;var t;if(null===e)return i("SSE endpoint not available, falling back to polling."),void await Ce();i(`Starting SSE queue listener on ${e}`),Te=new EventSource(e),$.setActiveSSEConnection(),Te.addEventListener("connected",(async e=>{i("SSE connection received:"),$.setActiveSSEConnection(),$.setUseSSEFlag(!0)})),Te.addEventListener("messages",(async e=>{try{var t=JSON.parse(e.data);i("SSE message received:"),await ae(t),await Y(t),await ke()}catch(e){i("Failed to parse SSE message"),qe()}})),Te.addEventListener("error",(async e=>{i("SSE error received:"),qe()})),Te.addEventListener("heartbeat",(async e=>{i("SSE heartbeat received:"),$.setActiveSSEConnection(),$.setUseSSEFlag(!0)}))}()}()))),1e3)):i("User token not setup, queue not started.")}async function ke(){var e=await async function(){const e=await ee();return e?(p(e)??[]).filter((t=>{const{broadcast:n}=t.properties.gist,s=p(ne(e,t.queueId))??!0,i=p(te(e,t.queueId))||0,a=0===n.frequency.count;return s&&(a||i<n.frequency.count)})):[]}(),t=await async function(){const e=await oe();if(!e)return[];const t=p(e)??[],n=await async function(){const e=await re();return e?p(e)??[]:[]}();return t.filter((e=>!n.includes(e.queueId)))}(),n=e.concat(t);i(`Messages in local queue: ${n.length}`);var s=n.sort(((e,t)=>e.priority-t.priority));for(const e of s)await Pe(e)}async function Pe(e){var t=O(e);if(t.hasRouteRule){var n=Re.currentRoute;null==n&&(n=new URL(window.location.href).pathname);var s=t.routeRule;if(i(`Verifying route against rule: ${s}`),!new RegExp(s).test(n))return i(`Route ${n} does not match rule.`),!1}if(t.hasPosition&&(e.position=t.position),t.persistent||function(e){if(!Z(e))return!1;const{broadcast:t}=e.properties.gist;return 0===t.frequency.delay&&0===t.frequency.count}(e)||!await async function(e){const t=await ue(e);return!!t&&null!==p(t)}(e.queueId)){var a;return(a=t.isEmbedded?await de(e,t.elementId):await ce(e))&&async function(e){const t=await ue(e);if(!t)return!1;h(t,!0,new Date(Date.now()+5e3))}(e.queueId),a}return i(`Not showing message with queueId ${e.queueId} because its already loading.`),!1}async function Ce(){if(U())if(Re.isDocumentVisible)if(null===p(k)){var e=await async function(){var e;try{if(!D){D=!0;var t={"X-Gist-User-Anonymous":L(),"Content-Language":null!==p(x)?p(x):navigator.language};if("3"===$.getQueueAPIVersion())e=await E().post(`/api/v3/users?sessionId=${C()}`,{},{headers:t});else{var n=(new Date).getTime();e=await E().post(`/api/v2/users?timestamp=${n}`,{},{headers:t})}}}catch(t){t.response?e=t.response:i(`Error getting user queue: ${t}`)}finally{D=!1,function(e){if(e&&e.headers){var t=e.headers["x-gist-queue-polling-interval"];t&&t>0&&(T=t)}var n=new Date((new Date).getTime()+1e3*T);h(k,T,n)}(e),function(e){if(e&&e.headers){var t=e.headers["x-cio-queue-version"];t&&$.setQueueAPIVersion(t)}}(e),function(e){const t="true"===e?.headers?.["x-cio-use-sse"]?.toLowerCase();$.setUseSSEFlag(t)}(e)}return e}(),t=[];e?(200===e.status||204===e.status?(i("200 response, updating local store."),ae(t=e.data),Y(t)):304===e.status&&i("304 response, using local store."),await ke()):i("There was an error while checking message queue.")}else i("Next queue pull scheduled for later.");else i("Document not visible, skipping queue check.");else i("User token reset, skipping queue check.")}function qe(){Te&&(i("Stopping SSE queue listener..."),Te.close(),Te=null,$.setUseSSEFlag(!1))}const Re=class{static async setup(e){this.events=new s,this.config={useAnonymousSession:void 0!==e.useAnonymousSession&&e.useAnonymousSession,siteId:e.siteId,dataCenter:e.dataCenter,env:void 0===e.env?"prod":e.env,logging:void 0!==e.logging&&e.logging,experiments:void 0!==e.experiments&&e.experiments},this.currentMessages=[],this.overlayInstanceId=null,this.currentRoute=null,this.isDocumentVisible=!0,this.config.isPreviewSession=function(){const e=new URLSearchParams(window.location.search).get("cioPreviewId");return e&&(sessionStorage.setItem(f,!1),Re.setUserToken(e),i(`Preview mode enabled with user token: ${e}`)),!v()}(),i(`Setup complete on ${this.config.env} environment.`),!this.config.isPreviewSession&&this.config.useAnonymousSession&&M(),await De(),document.addEventListener("visibilitychange",(async()=>{"hidden"===document.visibilityState?this.isDocumentVisible=!1:(this.isDocumentVisible=!0,await ke())}),!1)}static async setCurrentRoute(e){this.currentRoute=e,i(`Current route set to: ${e}`),await ke()}static async setUserToken(e,t){this.config.isPreviewSession||(function(e,t){void 0===t&&(t=new Date).setDate(t.getDate()+30),h(q,e,t),L()&&(w(k),w(R)),i(`Set user token "${e}" with expiry date set to ${t}`)}(e,t),await De())}static setUserLocale(e){var t;h(x,t=e),i(`Set user locate to "${t}"`)}static async clearUserToken(){this.config.isPreviewSession||(w(q),i("Cleared user token"),this.config.useAnonymousSession&&M(),qe(),await De())}static async dismissMessage(e){var t=we(e);await ge(t),await le(t),await $e(t),await ke()}static async embedMessage(e,t){var n=await de(e,t);return n?n.instanceId:null}static async showMessage(e){var t=await ce(e);return t?t.instanceId:null}static messageShown(e){i(`Message shown: ${e.messageId}`),this.events.dispatch("messageShown",e)}static messageDismissed(e){null!==e&&(i(`Message dismissed: ${e.messageId}`),this.events.dispatch("messageDismissed",e))}static messageError(e){i(`Message error: ${e.messageId}`),this.events.dispatch("messageError",e)}static messageAction(e,t,n){i(`Message action: ${e.currentRoute}, ${t} with name ${n} on ${e.instanceId}`),this.events.dispatch("messageAction",{message:e,action:t,name:n})}}},44:(e,t,n)=>{const s=n(548).A;e.exports=s}},t={};function n(s){var i=t[s];if(void 0!==i)return i.exports;var a=t[s]={exports:{}};return e[s](a,a.exports,n),a.exports}return n.d=(e,t)=>{for(var s in t)n.o(t,s)&&!n.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n(44)})()));
|
package/package.json
CHANGED
package/src/gist.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import EventEmitter from "./utilities/event-emitter";
|
|
2
2
|
import { log } from "./utilities/log";
|
|
3
|
-
import { startQueueListener, checkMessageQueue } from "./managers/queue-manager";
|
|
3
|
+
import { startQueueListener, checkMessageQueue, stopSSEListener } from "./managers/queue-manager";
|
|
4
4
|
import { setUserToken, clearUserToken, useGuestSession } from "./managers/user-manager";
|
|
5
5
|
import { showMessage, embedMessage, hideMessage, removePersistentMessage, fetchMessageByInstanceId, logBroadcastDismissedLocally } from "./managers/message-manager";
|
|
6
6
|
import { setUserLocale } from "./managers/locale-manager";
|
|
@@ -63,6 +63,7 @@ export default class {
|
|
|
63
63
|
if (this.config.useAnonymousSession) {
|
|
64
64
|
useGuestSession();
|
|
65
65
|
}
|
|
66
|
+
stopSSEListener();
|
|
66
67
|
await startQueueListener();
|
|
67
68
|
}
|
|
68
69
|
|
|
@@ -98,8 +98,6 @@ function resetEmbedState(message) {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
async function resetOverlayState(hideFirst, message) {
|
|
101
|
-
removeMessageByInstanceId(message.instanceId);
|
|
102
|
-
Gist.overlayInstanceId = null;
|
|
103
101
|
if (hideFirst) {
|
|
104
102
|
await hideOverlayComponent();
|
|
105
103
|
} else {
|
|
@@ -110,6 +108,9 @@ async function resetOverlayState(hideFirst, message) {
|
|
|
110
108
|
window.removeEventListener('message', handleGistEvents);
|
|
111
109
|
window.removeEventListener('touchstart', handleTouchStartEvents);
|
|
112
110
|
}
|
|
111
|
+
|
|
112
|
+
removeMessageByInstanceId(message.instanceId);
|
|
113
|
+
Gist.overlayInstanceId = null;
|
|
113
114
|
}
|
|
114
115
|
|
|
115
116
|
function loadMessageComponent(message, elementId = null) {
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import Gist from '../gist';
|
|
2
2
|
import { log } from "../utilities/log";
|
|
3
|
-
import { getUserToken } from "./user-manager";
|
|
4
|
-
import { getUserQueue, userQueueNextPullCheckLocalStoreName } from "../services/queue-service";
|
|
3
|
+
import { getUserToken, isAnonymousUser } from "./user-manager";
|
|
4
|
+
import { getUserQueue, getQueueSSEEndpoint, userQueueNextPullCheckLocalStoreName } from "../services/queue-service";
|
|
5
5
|
import { showMessage, embedMessage } from "./message-manager";
|
|
6
6
|
import { resolveMessageProperties } from "./gist-properties-manager";
|
|
7
7
|
import { getKeyFromLocalStore } from '../utilities/local-storage';
|
|
8
8
|
import { updateBroadcastsLocalStore, getEligibleBroadcasts, isShowAlwaysBroadcast } from './message-broadcast-manager';
|
|
9
9
|
import { updateQueueLocalStore, getMessagesFromLocalStore, isMessageLoading, setMessageLoading } from './message-user-queue-manager';
|
|
10
|
+
import { settings } from '../services/settings';
|
|
10
11
|
|
|
11
12
|
var sleep = time => new Promise(resolve => setTimeout(resolve, time))
|
|
12
13
|
var poll = (promiseFn, time) => promiseFn().then(sleep(time).then(() => poll(promiseFn, time)));
|
|
13
14
|
var pollingSetup = false;
|
|
15
|
+
let sseSource = null;
|
|
14
16
|
|
|
15
17
|
export async function startQueueListener() {
|
|
16
18
|
if (!pollingSetup) {
|
|
@@ -22,7 +24,7 @@ export async function startQueueListener() {
|
|
|
22
24
|
log("User token not setup, queue not started.");
|
|
23
25
|
}
|
|
24
26
|
} else {
|
|
25
|
-
checkMessageQueue();
|
|
27
|
+
await checkMessageQueue();
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
30
|
|
|
@@ -42,7 +44,7 @@ export async function checkMessageQueue() {
|
|
|
42
44
|
async function handleMessage(message) {
|
|
43
45
|
var messageProperties = resolveMessageProperties(message);
|
|
44
46
|
if (messageProperties.hasRouteRule) {
|
|
45
|
-
var currentUrl = Gist.currentRoute
|
|
47
|
+
var currentUrl = Gist.currentRoute;
|
|
46
48
|
if (currentUrl == null) {
|
|
47
49
|
currentUrl = new URL(window.location.href).pathname;
|
|
48
50
|
}
|
|
@@ -75,6 +77,23 @@ async function handleMessage(message) {
|
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
export async function pullMessagesFromQueue() {
|
|
80
|
+
// If SSE connection is already active, just check the local queue
|
|
81
|
+
if (settings.hasActiveSSEConnection()) {
|
|
82
|
+
await checkMessageQueue();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// If SSE is enabled and user is not anonymous, set up SSE listener
|
|
87
|
+
if (settings.useSSE() && !isAnonymousUser()) {
|
|
88
|
+
await setupSSEQueueListener();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Fall back to polling
|
|
93
|
+
await checkQueueThroughPolling();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function checkQueueThroughPolling() {
|
|
78
97
|
if (getUserToken()) {
|
|
79
98
|
if (Gist.isDocumentVisible) {
|
|
80
99
|
// We're using the TTL as a way to determine if we should check the queue, so if the key is not there, we check the queue.
|
|
@@ -87,8 +106,7 @@ export async function pullMessagesFromQueue() {
|
|
|
87
106
|
responseData = response.data;
|
|
88
107
|
updateQueueLocalStore(responseData);
|
|
89
108
|
updateBroadcastsLocalStore(responseData);
|
|
90
|
-
}
|
|
91
|
-
else if (response.status === 304) {
|
|
109
|
+
} else if (response.status === 304) {
|
|
92
110
|
log("304 response, using local store.");
|
|
93
111
|
}
|
|
94
112
|
await checkMessageQueue();
|
|
@@ -99,9 +117,66 @@ export async function pullMessagesFromQueue() {
|
|
|
99
117
|
log(`Next queue pull scheduled for later.`);
|
|
100
118
|
}
|
|
101
119
|
} else {
|
|
102
|
-
log(`Document not visible, skipping queue check.`);
|
|
120
|
+
log(`Document not visible, skipping queue check.`);
|
|
103
121
|
}
|
|
104
122
|
} else {
|
|
105
123
|
log(`User token reset, skipping queue check.`);
|
|
106
124
|
}
|
|
107
|
-
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function setupSSEQueueListener() {
|
|
128
|
+
const sseURL = getQueueSSEEndpoint();
|
|
129
|
+
if (sseURL === null) {
|
|
130
|
+
log("SSE endpoint not available, falling back to polling.");
|
|
131
|
+
await checkQueueThroughPolling();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
log(`Starting SSE queue listener on ${sseURL}`);
|
|
135
|
+
sseSource = new EventSource(sseURL);
|
|
136
|
+
settings.setActiveSSEConnection();
|
|
137
|
+
|
|
138
|
+
sseSource.addEventListener("connected", async (event) => {
|
|
139
|
+
log("SSE connection received:", event);
|
|
140
|
+
settings.setActiveSSEConnection();
|
|
141
|
+
settings.setUseSSEFlag(true);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
sseSource.addEventListener("messages", async (event) => {
|
|
145
|
+
try {
|
|
146
|
+
var messages = JSON.parse(event.data);
|
|
147
|
+
log("SSE message received:", messages);
|
|
148
|
+
await updateQueueLocalStore(messages);
|
|
149
|
+
await updateBroadcastsLocalStore(messages);
|
|
150
|
+
await checkMessageQueue();
|
|
151
|
+
} catch (e) {
|
|
152
|
+
log("Failed to parse SSE message", e);
|
|
153
|
+
stopSSEListener();
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
sseSource.addEventListener("error", async (event) => {
|
|
158
|
+
log("SSE error received:", event);
|
|
159
|
+
stopSSEListener();
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
sseSource.addEventListener("heartbeat", async (event) => {
|
|
163
|
+
log("SSE heartbeat received:", event);
|
|
164
|
+
settings.setActiveSSEConnection();
|
|
165
|
+
settings.setUseSSEFlag(true);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export function stopSSEListener() {
|
|
170
|
+
// No active SSE connection to stop
|
|
171
|
+
if (!sseSource) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Close the connection and clean up
|
|
176
|
+
log("Stopping SSE queue listener...");
|
|
177
|
+
sseSource.close();
|
|
178
|
+
sseSource = null;
|
|
179
|
+
|
|
180
|
+
// Update settings to reflect disconnected state
|
|
181
|
+
settings.setUseSSEFlag(false);
|
|
182
|
+
}
|
|
@@ -47,6 +47,10 @@ export function useGuestSession() {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
export function isAnonymousUser() {
|
|
51
|
+
return isUsingGuestUserToken();
|
|
52
|
+
}
|
|
53
|
+
|
|
50
54
|
export async function getHashedUserToken() {
|
|
51
55
|
var userToken = getUserToken();
|
|
52
56
|
if (userToken === null) {
|
|
@@ -55,6 +59,14 @@ export async function getHashedUserToken() {
|
|
|
55
59
|
return await hashString(userToken);
|
|
56
60
|
}
|
|
57
61
|
|
|
62
|
+
export function getEncodedUserToken() {
|
|
63
|
+
var userToken = getUserToken();
|
|
64
|
+
if (userToken === null) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
return btoa(userToken);
|
|
68
|
+
}
|
|
69
|
+
|
|
58
70
|
export function clearUserToken() {
|
|
59
71
|
clearKeyFromLocalStore(userTokenLocalStoreName);
|
|
60
72
|
log(`Cleared user token`);
|
package/src/services/network.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Gist from '../gist';
|
|
2
2
|
import { settings } from './settings';
|
|
3
|
-
import {
|
|
3
|
+
import { getEncodedUserToken } from "../managers/user-manager";
|
|
4
4
|
|
|
5
5
|
export function UserNetworkInstance() {
|
|
6
6
|
const baseURL =
|
|
@@ -13,9 +13,9 @@ export function UserNetworkInstance() {
|
|
|
13
13
|
'X-CIO-Client-Platform': 'web',
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
const userToken =
|
|
16
|
+
const userToken = getEncodedUserToken();
|
|
17
17
|
if (userToken != null) {
|
|
18
|
-
defaultHeaders['X-Gist-Encoded-User-Token'] =
|
|
18
|
+
defaultHeaders['X-Gist-Encoded-User-Token'] = userToken;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
async function request(path, options = {}) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import Gist from '../gist';
|
|
1
2
|
import { UserNetworkInstance } from './network';
|
|
2
3
|
import { getKeyFromLocalStore, setKeyToLocalStore } from '../utilities/local-storage';
|
|
3
4
|
import { log } from "../utilities/log";
|
|
4
|
-
import { isUsingGuestUserToken } from '../managers/user-manager';
|
|
5
|
+
import { isUsingGuestUserToken, getEncodedUserToken } from '../managers/user-manager';
|
|
5
6
|
import { getUserLocale } from '../managers/locale-manager';
|
|
6
7
|
import { settings } from './settings';
|
|
7
8
|
import { v4 as uuidv4 } from 'uuid';
|
|
@@ -39,6 +40,7 @@ export async function getUserQueue() {
|
|
|
39
40
|
checkInProgress = false;
|
|
40
41
|
scheduleNextQueuePull(response);
|
|
41
42
|
setQueueAPIVersion(response);
|
|
43
|
+
setQueueUseSSE(response);
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
return response;
|
|
@@ -53,6 +55,11 @@ function setQueueAPIVersion(response) {
|
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
|
|
58
|
+
function setQueueUseSSE(response) {
|
|
59
|
+
const useSSE = response?.headers?.["x-cio-use-sse"]?.toLowerCase() === "true";
|
|
60
|
+
settings.setUseSSEFlag(useSSE);
|
|
61
|
+
}
|
|
62
|
+
|
|
56
63
|
function getSessionId() {
|
|
57
64
|
var sessionId = getKeyFromLocalStore(sessionIdLocalStoreName);
|
|
58
65
|
if (!sessionId) {
|
|
@@ -73,3 +80,12 @@ function scheduleNextQueuePull(response) {
|
|
|
73
80
|
var expiryDate = new Date(new Date().getTime() + currentPollingDelayInSeconds * 1000);
|
|
74
81
|
setKeyToLocalStore(userQueueNextPullCheckLocalStoreName, currentPollingDelayInSeconds, expiryDate);
|
|
75
82
|
}
|
|
83
|
+
|
|
84
|
+
export function getQueueSSEEndpoint() {
|
|
85
|
+
var encodedUserToken = getEncodedUserToken();
|
|
86
|
+
if (encodedUserToken === null) {
|
|
87
|
+
log("No user token available for SSE endpoint.");
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
return settings.GIST_QUEUE_REALTIME_API_ENDPOINT[Gist.config.env] + `/api/v3/sse?userToken=${encodedUserToken}&siteId=${Gist.config.siteId}&sessionId=${getSessionId()}`;
|
|
91
|
+
}
|
package/src/services/settings.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { getKeyFromLocalStore, setKeyToLocalStore } from '../utilities/local-storage';
|
|
2
2
|
import { log } from '../utilities/log';
|
|
3
3
|
const userQueueVersionLocalStoreName = "gist.web.userQueueVersion";
|
|
4
|
+
const userQueueUseSSELocalStoreName = "gist.web.userQueueUseSSE";
|
|
5
|
+
const userQueueActiveSSEConnectionLocalStoreName = "gist.web.activeSSEConnection";
|
|
4
6
|
|
|
5
7
|
export const settings = {
|
|
6
8
|
RENDERER_HOST: "https://code.gist.build",
|
|
@@ -19,6 +21,11 @@ export const settings = {
|
|
|
19
21
|
"dev": "https://consumer.cloud.dev.gist.build",
|
|
20
22
|
"local": "http://api.local.gist.build:86"
|
|
21
23
|
},
|
|
24
|
+
GIST_QUEUE_REALTIME_API_ENDPOINT: {
|
|
25
|
+
"prod": "https://realtime.cloud.gist.build",
|
|
26
|
+
"dev": "https://realtime.cloud.dev.gist.build",
|
|
27
|
+
"local": "http://api.local.gist.build:3000"
|
|
28
|
+
},
|
|
22
29
|
GIST_VIEW_ENDPOINT: {
|
|
23
30
|
"prod": "https://renderer.gist.build/3.0",
|
|
24
31
|
"dev": "https://renderer.gist.build/3.0",
|
|
@@ -31,5 +38,18 @@ export const settings = {
|
|
|
31
38
|
// The Queue API version TTL is renewed with every poll request and extended by 30 minutes.
|
|
32
39
|
setKeyToLocalStore(userQueueVersionLocalStoreName, version, new Date(new Date().getTime() + 1800000));
|
|
33
40
|
log(`Set user queue version to "${version}"`);
|
|
41
|
+
},
|
|
42
|
+
useSSE: function() {
|
|
43
|
+
return getKeyFromLocalStore(userQueueUseSSELocalStoreName) ?? false;
|
|
44
|
+
},
|
|
45
|
+
setUseSSEFlag: function(useSSE) {
|
|
46
|
+
setKeyToLocalStore(userQueueUseSSELocalStoreName, useSSE, new Date(new Date().getTime() + 60000));
|
|
47
|
+
log(`Set user uses SSE to "${useSSE}"`);
|
|
48
|
+
},
|
|
49
|
+
setActiveSSEConnection: function() {
|
|
50
|
+
setKeyToLocalStore(userQueueActiveSSEConnectionLocalStoreName, true, new Date(new Date().getTime() + 31000));
|
|
51
|
+
},
|
|
52
|
+
hasActiveSSEConnection: function() {
|
|
53
|
+
return getKeyFromLocalStore(userQueueActiveSSEConnectionLocalStoreName) ?? false;
|
|
34
54
|
}
|
|
35
55
|
}
|