UNPKG

@preset-sdk/embedded

Version:

Frontend SDK for embedding Preset data analytics into your own application

2 lines 6.83 kB
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.presetSdk=t():e.presetSdk=t()}(globalThis,(function(){return(()=>{"use strict";var e={d:(t,r)=>{for(var o in r)e.o(r,o)&&!e.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:r[o]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{_initComms:()=>c,embedDashboard:()=>d});var r=function(e){return e.GET="get",e.REPLY="reply",e.EMIT="emit",e.ERROR="error",e}(r||{});class o{constructor(e){this.port=void 0,this.name="",this.methods={},this.incrementor=1,this.debugMode=void 0,this.isInitialised=void 0,e&&this.init(e)}init(e){if(this.isInitialised)return void this.logError("already initialized");const{port:t,name:o="switchboard",debug:s=!1}=e;this.port=t,this.name=o,this.debugMode=s,t.addEventListener("message",(async e=>{this.log("message received",e);const t=e.data;if(function(e){return e.switchboardAction===r.GET}(t))this.port.postMessage(await this.getMethodResult(t));else if(function(e){return e.switchboardAction===r.EMIT}(t)){const{method:e,args:r}=t,o=this.methods[e];o&&o(r)}})),this.isInitialised=!0}async getMethodResult({messageId:e,method:t,args:o}){const s=this.methods[t];if(null==s)return{switchboardAction:r.ERROR,messageId:e,error:`[${this.name}] Method "${t}" is not defined`};try{const t=await s(o);return{switchboardAction:r.REPLY,messageId:e,result:t}}catch(o){return this.logError(o),{switchboardAction:r.ERROR,messageId:e,error:`[${this.name}] Method "${t}" threw an error`}}}defineMethod(e,t){this.methods[e]=t}get(e,t){return new Promise(((o,s)=>{if(!this.isInitialised)return void s(new Error("Switchboard not initialised"));const n=this.getNewMessageId(),i=e=>{const t=e.data;if(t.messageId===n)if(this.port.removeEventListener("message",i),function(e){return e.switchboardAction===r.REPLY}(t))o(t.result);else{const e=function(e){return e.switchboardAction===r.ERROR}(t)?t.error:"Unexpected response message";s(new Error(e))}};this.port.addEventListener("message",i),this.port.start();const a={switchboardAction:r.GET,method:e,messageId:n,args:t};this.port.postMessage(a)}))}emit(e,t){if(!this.isInitialised)return void this.logError("Switchboard not initialised");const o={switchboardAction:r.EMIT,method:e,args:t};this.port.postMessage(o)}start(){this.isInitialised?this.port.start():this.logError("Switchboard not initialised")}log(...e){this.debugMode&&console.debug(`[${this.name}]`,...e)}logError(...e){console.error(`[${this.name}]`,...e)}getNewMessageId(){return`m_${this.name}_${this.incrementor++}`}}new o;const s="__embedded_comms__",n={visible:"show_filters",expanded:"expand_filters"};class i extends Error{}function a(e){const t=function(e,t){if("string"!=typeof e)throw new i("Invalid token specified: must be a string");t||(t={});const r=!0===t.header?0:1,o=e.split(".")[r];if("string"!=typeof o)throw new i(`Invalid token specified: missing part #${r+1}`);let s;try{s=function(e){let t=e.replace(/-/g,"+").replace(/_/g,"/");switch(t.length%4){case 0:break;case 2:t+="==";break;case 3:t+="=";break;default:throw new Error("base64 string is not of the correct length")}try{return function(e){return decodeURIComponent(atob(e).replace(/(.)/g,((e,t)=>{let r=t.charCodeAt(0).toString(16).toUpperCase();return r.length<2&&(r="0"+r),"%"+r})))}(t)}catch(e){return atob(t)}}(o)}catch(e){throw new i(`Invalid token specified: invalid base64 for part #${r+1} (${e.message})`)}try{return JSON.parse(s)}catch(e){throw new i(`Invalid token specified: invalid json for part #${r+1} (${e.message})`)}}(e),r=new Date(/[^0-9\.]/g.test(t.exp)?t.exp:1e3*parseFloat(t.exp));return("Invalid Date"!==r.toString()?Math.max(1e4,r.getTime()-Date.now()):3e5)-5e3}async function d(e){let{id:t,supersetDomain:r,mountPoint:o,fetchGuestToken:s,dashboardUiConfig:i,debug:d=!1,iframeTitle:h="Embedded Dashboard",iframeSandboxExtras:l=[],referrerPolicy:g}=e;function m(){if(d){for(var e=arguments.length,r=new Array(e),o=0;o<e;o++)r[o]=arguments[o];console.debug(`[preset-frontend-sdk][dashboard ${t}]`,...r)}}var u;function f(){let e=0;return i&&(i.hideTitle&&(e+=1),i.hideTab&&(e+=2),i.hideChartControls&&(e+=8),i.emitDataMasks&&(e+=16),i.showRowLimitWarning&&(e+=32)),e}m("embedding"),(u=Element.prototype).hasOwnProperty("replaceChildren")||Object.defineProperty(u,"replaceChildren",{configurable:!0,enumerable:!0,value:function(){for(;this.firstChild;)this.removeChild(this.firstChild);for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];t.forEach((e=>{this.appendChild("string"==typeof e?document.createTextNode(e):e)}))}}),r.endsWith("/")&&(r=r.slice(0,-1));const[p,b]=await Promise.all([s(),async function(){return new Promise((e=>{const s=document.createElement("iframe"),a=i?{uiConfig:`${f()}`}:void 0,u=i?.filters||{},p=Object.keys(u),b={...a,...Object.fromEntries(p.map((e=>[n[e],u[e]]))),...i?.urlParams},w=Object.keys(b).length?"?"+new URLSearchParams(b).toString():"";s.sandbox.add("allow-same-origin"),s.sandbox.add("allow-scripts"),s.sandbox.add("allow-presentation"),s.sandbox.add("allow-downloads"),s.sandbox.add("allow-top-navigation"),s.sandbox.add("allow-forms"),s.sandbox.add("allow-popups"),l.forEach((e=>{s.sandbox.add(e)})),g&&(s.referrerPolicy=g),s.addEventListener("load",(()=>{const t=c(s.contentWindow,r,d);m("sent message channel to the iframe"),e(t)})),s.src=`${r}/embedded/${t}${w}`,s.title=h,o?.replaceChildren(s),m("placed the iframe")}))}()]);let w;return b.emit("guestToken",{guestToken:p}),m("sent guest token"),w=setTimeout((async function e(){const t=await s();b.emit("guestToken",{guestToken:t}),w=setTimeout(e,a(t))}),a(p)),{getScrollSize:()=>b.get("getScrollSize"),unmount:function(){m("unmounting"),o?.replaceChildren(),clearTimeout(w)},getDashboardPermalink:e=>b.get("getDashboardPermalink",{anchor:e}),getActiveTabs:()=>b.get("getActiveTabs"),observeDataMask:e=>{b.start(),b.defineMethod("observeDataMask",e)},getDataMask:()=>b.get("getDataMask"),setThemeConfig:async e=>{try{b.emit("setThemeConfig",{themeConfig:e}),m("Theme config sent successfully (or at least message dispatched)")}catch(e){throw m('Error sending theme config. Ensure the iframe side implements the "setThemeConfig" method.'),e}},getChartDataPayloads:e=>b.get("getChartDataPayloads",e)}}function c(e,t){let r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];const n=new MessageChannel,i=n.port1,a=n.port2;return e.postMessage({type:s,handshake:"port transfer"},t,[a]),new o({port:i,name:"preset-frontend-sdk",debug:r})}return i.prototype.name="InvalidTokenError",t})()})); //# sourceMappingURL=index.js.map