@interopio/desktop
Version:
JavaScript library for io.Connect Desktop clients.
1 lines • 422 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e="undefined"!=typeof globalThis?globalThis:e||self).desktop=e.desktop||{},e.desktop.browser=e.desktop.browser||{},e.desktop.browser.min=t())}(this,function(){"use strict";var e=1,t=2,n=3,i=4;function r(r){return r.type===n?"timestamp":r.type===t?"number":r.type===e?"string":r.type===i?"object":"unknown"}function o(e){return e.constructor===Date?"timestamp":"number"==typeof e?"number":"string"==typeof e?"string":"object"==typeof e?"object":"string"}function s(e){const t={},n=r(e);if("object"===n){const n=Object.keys(e.value).reduce((t,n)=>{const i=o(e.value[n]);if("object"===i){const i=a(e.value[n]);t[n]={type:"object",description:"",context:{},composite:i}}else t[n]={type:i,description:"",context:{}};return t},{});t.composite=n}return t.name=c(e.path.join("/")+"/"+e.name),t.type=n,t.description=e.description,t.context={},t}function a(e){return Object.keys(e).reduce((t,n)=>{const i=o(e[n]);return t[n]="object"===i?{type:"object",description:"",context:{},composite:a(e[n])}:{type:i,description:"",context:{}},t},{})}function c(e){return void 0!==e&&e.length>0&&"/"!==e[0]?"/"+e:e}function d(e){return"timestamp"===r(e)?Date.now():h(e.value)}function h(e){return"object"!=typeof e?e:Object.keys(e).reduce((t,n)=>{const i=e[n];return"object"==typeof i&&i.constructor!==Date?t[n]=h(i):i.constructor===Date?t[n]=new Date(i).getTime():i.constructor===Boolean?t[n]=i.toString():t[n]=i,t},{})}function l(e){return e.reduce((e,t)=>e.concat(Array.isArray(t)?l(t):t),[])}function u(e){const t=l(e.root.getAggregateState()),n=t.sort((e,t)=>e.state?t.state?t.state-e.state:-1:1)[0];const i=function(e){let t="";return e.forEach((e,n,i)=>{const r=e.path.join(".");n===i.length-1?t+=r+"."+e.name+": "+e.description:t+=r+"."+e.name+": "+e.description+","}),t.length>100?t.slice(0,100)+"...":t}(t);return{description:i,value:n.state}}var p=(e,t,n)=>{if(null===e||"object"!=typeof e)throw new Error("Missing definition");if(null===t||"object"!=typeof t)throw new Error("Missing parent");if(null===n||"object"!=typeof n)throw new Error("Missing transport")};class g{definition;system;transport;value;type;path=[];name;description;get repo(){return this.system?.repo}get id(){return`${this.system.path}/${name}`}constructor(e,t,n,i,r){this.definition=e,this.system=t,this.transport=n,this.value=i,this.type=r,p(e,t,n),this.path=t.path.slice(0),this.path.push(t.name),this.name=e.name,this.description=e.description,n.createMetric(this)}update(e){return this.value=e,this.transport.updateMetric(this)}}class f extends g{constructor(e,n,i,r){super(e,n,i,r,t)}incrementBy(e){this.update(this.value+e)}increment(){this.incrementBy(1)}decrement(){this.incrementBy(-1)}decrementBy(e){this.incrementBy(-1*e)}}class m extends g{constructor(e,t,n,r){super(e,t,n,r,i)}update(e){return this.mergeValues(e),this.transport.updateMetric(this)}mergeValues(e){return Object.keys(this.value).forEach(t=>{void 0!==e[t]&&(this.value[t]=e[t])})}}class y extends g{constructor(t,n,i,r){super(t,n,i,r,e)}}class w extends g{constructor(e,t,i,r){super(e,t,i,r,n)}now(){this.update(new Date)}}function v(r,o,s,a,c){if(!o)throw new Error("Repository is required");if(!s)throw new Error("Transport is required");const d=s,h=r,l=c||"",u=o,p=a,g=function e(t){if(!t||!t.parent)return[];const n=e(t.parent);return n.push(t.name),n}(a);let b={};const _=(C="/",((I=g)&&I.length>0?I.join(C):"")+r);var I,C;const A=o.root,T=[],S=[];function k(e,t,n,i){let r={name:""};r="string"==typeof e?{name:e}:e;const o=S.filter(e=>e.name===r.name);if(o.length>0){const e=o[0];if(e.type!==t)throw new Error(`A metric named ${r.name} is already defined with different type.`);return void 0!==n&&e.update(n).catch(()=>{}),e}const s=i(r);return S.push(s),s}const x={get name(){return h},get description(){return l},get repo(){return u},get parent(){return p},path:g,id:_,root:A,get subSystems(){return T},get metrics(){return S},subSystem:function(e,t){if(!e||0===e.length)throw new Error("name is required");const n=T.filter(t=>t.name===e);if(n.length>0)return n[0];const i=v(e,u,d,x,t);return T.push(i),i},getState:()=>b,setState:function(e,t){b={state:e,description:t},d.updateSystem(x,b)},stringMetric:function(t,n){return k(t,e,n,e=>new y(e,x,d,n))},timestampMetric:function(e,t){return k(e,n,t,e=>new w(e,x,d,t))},objectMetric:function(e,t){return k(e,i,t,e=>new m(e,x,d,t))},numberMetric:function(e,n){return k(e,t,n,e=>new f(e,x,d,n))},getAggregateState:function(){const e=[];return Object.keys(b).length>0&&e.push({name:h,path:g,state:b.state,description:b.description}),T.forEach(t=>{const n=t.getAggregateState();n.length>0&&e.push(...n)}),e}};return d.createSystem(x),x}class b{root;constructor(e,t){t.init(this),this.root=v("",this,t),this.addSystemMetrics(this.root,e.clickStream||void 0===e.clickStream)}addSystemMetrics(e,t){if("undefined"!=typeof navigator&&e.stringMetric("UserAgent",navigator.userAgent),t&&"undefined"!=typeof document){const t=e.subSystem("ClickStream"),n=e=>{if(!e.target)return;const n=e.target,i=n?n.getAttribute("class")??"":"";t.objectMetric("LastBrowserEvent",{type:"click",timestamp:new Date,target:{className:i,id:n.id,type:"<"+n.tagName.toLowerCase()+">",href:n.href||""}})};t.objectMetric("Page",{title:document.title,page:window.location.href}),document.addEventListener?document.addEventListener("click",n):document.attachEvent("onclick",n)}e.stringMetric("StartTime",(new Date).toString());const n=e.stringMetric("StartURL",""),i=e.stringMetric("AppName","");if("undefined"!=typeof window){if(void 0!==window.location){const e=window.location.href;n.update(e)}void 0!==window.glue42gd&&i.update(window.glue42gd.appName)}}}class _{init(e){}createSystem(e){return Promise.resolve()}updateSystem(e,t){return Promise.resolve()}createMetric(e){return Promise.resolve()}updateMetric(e){return Promise.resolve()}}class I{api;lastCount=0;initialPublishTimeout=1e4;publishInterval=6e4;system;constructor(e,t,n){this.api=e,this.initialPublishTimeout=t??this.initialPublishTimeout,this.publishInterval=n??this.publishInterval,this.scheduleCollection(),this.system=this.api.subSystem("performance","Performance data published by the web application")}scheduleCollection(){setTimeout(()=>{this.collect(),setInterval(()=>{this.collect()},this.publishInterval)},this.initialPublishTimeout)}collect(){try{this.collectMemory(),this.collectEntries()}catch{}}collectMemory(){const e=window.performance.memory;this.system.stringMetric("memory",JSON.stringify({totalJSHeapSize:e.totalJSHeapSize,usedJSHeapSize:e.usedJSHeapSize}))}collectEntries(){const e=window.performance.getEntries();if(e.length<=this.lastCount)return;this.lastCount=e.length;const t=e.map(e=>e.toJSON());this.system.stringMetric("entries",JSON.stringify(t))}}var C=e=>{let t;t=e.connection&&"object"==typeof e.connection?function(e,t){if(!e||"object"!=typeof e)throw new Error("Connection is required parameter");let n,i;const r=e=>{o(e.root)},o=e=>{a(e),e.metrics.forEach(e=>{h(e)}),e.subSystems.forEach(e=>{o(e)})},a=async e=>{if(void 0===e.parent)return;await n;const r={type:"define",metrics:[{name:c(e.path.join("/")+"/"+e.name+"/State"),type:"object",composite:{Description:{type:"string",description:""},Value:{type:"number",description:""}},description:"System state",context:{}}]};i.sendFireAndForget(r).catch(n=>{t.logger.warn(`Failed to send define for system state metric of ${e.name}: ${JSON.stringify(n)}`)})},h=async e=>{const r=p(e);await n;const o={type:"define",metrics:[s(r)]};i.sendFireAndForget(o).catch(n=>{t.logger.warn(`Failed to send define for metric ${e.name}: ${JSON.stringify(n)}`)}),void 0!==r.value&&l(r)},l=e=>{if(g()){const n=d(e),r={type:"publish",values:[{name:c(e.path.join("/")+"/"+e.name),value:n,timestamp:Date.now()}]};return i.sendFireAndForget(r).catch(n=>{t.logger.warn(`Failed to publish metric ${e.name}: ${JSON.stringify(n)}`)})}return Promise.resolve()},p=e=>{const t={...e};return"object"==typeof e.value&&null!==e.value&&(t.value={...e.value}),t},g=()=>{try{return(t.canUpdateMetric??(()=>!0))()}catch{return!0}};return{init:o=>{let s;n=new Promise(e=>{s=e}),i=e.domain("metrics"),i.onJoined(e=>{!e&&s&&(s(),s=void 0);const n={type:"define",metrics:[{name:"/State",type:"object",composite:{Description:{type:"string",description:""},Value:{type:"number",description:""}},description:"System state",context:{}}]};i.sendFireAndForget(n).catch(e=>{t.logger.warn(`Failed to send define for root state metric: ${JSON.stringify(e)}`)}),e&&r(o)}),i.join({system:t.system,service:t.service,instance:t.instance})},createSystem:a,updateSystem:async(r,o)=>{await n;const s={type:"publish",values:[{name:c(r.path.join("/")+"/"+r.name+"/State"),value:{Description:o.description,Value:o.state},timestamp:Date.now()}]};i.sendFireAndForget(s).catch(e=>{t.logger.warn(`Failed to send update for system state metric of ${r.name}: ${JSON.stringify(e)}`)});const a=u(r),d={type:"publish",peer_id:e.peerId,values:[{name:"/State",value:{Description:a.description,Value:a.value},timestamp:Date.now()}]};i.sendFireAndForget(d).catch(e=>{t.logger.warn(`Failed to send update for root state metric of ${r.name}: ${JSON.stringify(e)}`)})},createMetric:h,updateMetric:async e=>{const t=p(e);await n,l(t)}}}(e.connection,e):new _;let n=new b(e,t).root;e.disableAutoAppSystem||(n=n.subSystem("App"));const i=function(e){const t=e.subSystem("reporting"),n={name:"features"};let i;const r=(e,r,o)=>{if(void 0===e||""===e)throw new Error("name is mandatory");if(void 0===r||""===r)throw new Error("action is mandatory");if(void 0===o||""===o)throw new Error("payload is mandatory");i?i.update({name:e,action:r,payload:o}):i=t.objectMetric(n,{name:e,action:r,payload:o})};return e.featureMetric=r,e}(n);return function(e,t){if("undefined"==typeof window)return;const n=window?.glue42gd?.metrics?.pagePerformanceMetrics;n&&(t=n);t?.enabled&&new I(e,t.initialPublishTimeout,t.publishInterval)}(i,e.pagePerformanceMetrics),i};var A="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function T(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function S(e){if(e&&e.errorHandling&&"function"!=typeof e.errorHandling&&"log"!==e.errorHandling&&"silent"!==e.errorHandling&&"throw"!==e.errorHandling)throw new Error('Invalid options passed to createRegistry. Prop errorHandling should be ["log" | "silent" | "throw" | (err) => void], but '+typeof e.errorHandling+" was passed");var t=e&&"function"==typeof e.errorHandling&&e.errorHandling,n={};function i(n,i){var r=n instanceof Error?n:new Error(n);if(t)t(r);else{var o='[ERROR] callback-registry: User callback for key "'+i+'" failed: '+r.stack;if(e)switch(e.errorHandling){case"log":return console.error(o);case"silent":return;case"throw":throw new Error(o)}console.error(o)}}return{add:function(e,t,r){var o=n[e];return o||(o=[],n[e]=o),o.push(t),r&&setTimeout(function(){r.forEach(function(r){var o;if(null===(o=n[e])||void 0===o?void 0:o.includes(t))try{Array.isArray(r)?t.apply(void 0,r):t.apply(void 0,[r])}catch(t){i(t,e)}})},0),function(){var i=n[e];i&&(0===(i=i.reduce(function(e,n,i){return n===t&&e.length===i||e.push(n),e},[])).length?delete n[e]:n[e]=i)}},execute:function(e){for(var t=[],r=1;r<arguments.length;r++)t[r-1]=arguments[r];var o=n[e];if(!o||0===o.length)return[];var s=[];return o.forEach(function(n){try{var r=n.apply(void 0,t);s.push(r)}catch(t){s.push(void 0),i(t,e)}}),s},clear:function(){n={}},clearKey:function(e){n[e]&&delete n[e]}}}S.default=S;var k=T(S);class x{gw;registry=k();client;constructor(e,t){this.gw=e.facade,this.gw.connect((e,t)=>{this.messageHandler(t)}).then(e=>{this.client=e})}get isObjectBasedTransport(){return!0}sendObject(e){return this.client?(this.client.send(e),Promise.resolve(void 0)):Promise.reject("not connected")}send(e){return Promise.reject("not supported")}onMessage(e){return this.registry.add("onMessage",e)}onConnectedChanged(e){return e(!0),()=>{}}close(){return Promise.resolve()}open(){return Promise.resolve()}name(){return"in-memory"}reconnect(){return Promise.resolve()}messageHandler(e){this.registry.execute("onMessage",e)}}class E{logger;worker;registry=k();constructor(e,t){this.logger=t,this.worker=new SharedWorker(e),this.worker.port.onmessage=e=>{this.messageHandler(e.data)}}get isObjectBasedTransport(){return!0}sendObject(e){return this.worker.port.postMessage(e),Promise.resolve()}send(e){return Promise.reject("not supported")}onMessage(e){return this.registry.add("onMessage",e)}onConnectedChanged(e){return e(!0),()=>{}}close(){return Promise.resolve()}open(){return Promise.resolve()}name(){return"shared-worker"}reconnect(){return Promise.resolve()}messageHandler(e){this.registry.execute("onMessage",e)}}let P=class e{static isNode(){if(void 0!==e._isNode)return e._isNode;if("undefined"!=typeof window)return e._isNode=!1,!1;try{e._isNode="[object process]"===Object.prototype.toString.call(global.process)}catch(t){e._isNode=!1}return e._isNode}static _isNode},M=class{static delay(e){return new Promise(t=>setTimeout(t,e))}resolve;reject;promise;rejected=!1;resolved=!1;get ended(){return this.rejected||this.resolved}constructor(){this.promise=new Promise((e,t)=>{this.resolve=t=>{this.resolved=!0,e(t)},this.reject=e=>{this.rejected=!0,t(e)}})}};const R={};function N(e){const t=R[e];if(t)return t;const n=[];function i(){return(new Date).getTime()}const r=i();let o,s;function a(e,t){const r=t??i();let o=0;n.length>0&&(o=r-n[n.length-1].time),n.push({name:e,time:r,diff:o})}a("start",r);const c={get startTime(){return r},get endTime(){return o},get period(){return s},stop:function(){return o=i(),a("end",o),s=o-r,s},mark:a,marks:n};return R[e]=c,c}const O=P.isNode()?null:window.WebSocket;class j{ws;logger;settings;startupTimer=N("connection");_running=!0;_registry=k();wsRequests=[];constructor(e,t){if(this.settings=e,this.logger=t,!this.settings.ws)throw new Error("ws is missing")}onMessage(e){return this._registry.add("onMessage",e)}send(e,t){return new Promise((t,n)=>{this.waitForSocketConnection(()=>{try{this.ws?.send(e),t()}catch(e){n(e)}},n)})}open(){return this.logger.info("opening ws..."),this._running=!0,new Promise((e,t)=>{this.waitForSocketConnection(e,t)})}close(){return this._running=!1,this.ws&&this.ws.close(),Promise.resolve()}onConnectedChanged(e){return this._registry.add("onConnectedChanged",e)}name(){return this.settings.ws}reconnect(){this.ws?.close();const e=new M;return this.waitForSocketConnection(()=>{e.resolve()}),e.promise}waitForSocketConnection(e,t){t=t??(()=>{}),this._running?1!==this.ws?.readyState?(this.wsRequests.push({callback:e,failed:t}),this.wsRequests.length>1||this.openSocket()):e():t(`wait for socket on ${this.settings.ws} failed - socket closed by user`)}async openSocket(e,t){if(this.logger.info(`opening ws to ${this.settings.ws}, retryInterval: ${e}, retriesLeft: ${t}...`),this.startupTimer.mark("opening-socket"),void 0===e&&(e=this.settings.reconnectInterval),void 0===t&&(t=this.settings.reconnectAttempts),void 0!==t){if(0===t)return void this.notifyForSocketState(`wait for socket on ${this.settings.ws} failed - no more retries left`);this.logger.debug(`will retry ${t} more times (every ${e} ms)`)}try{await this.initiateSocket(),this.startupTimer.mark("socket-initiated"),this.notifyForSocketState()}catch{setTimeout(()=>{const n=void 0===t?void 0:t-1;this.openSocket(e,n)},e)}}initiateSocket(){const e=new M;this.logger.debug(`initiating ws to ${this.settings.ws}...`),this.ws=new O(this.settings.ws??"");let t=!1;return this.ws.onerror=n=>{let i;try{i=JSON.stringify(n)}catch(e){const t=new WeakSet,r=(e,n)=>{if("object"==typeof n&&null!==n){if(t.has(n))return;t.add(n)}return n};i=JSON.stringify(n,r)}this.logger.info(`ws error - reason: ${i}`),e.reject("error"),t&&(t=!1,this.notifyForSocketState("error")),this.notifyStatusChanged(!1,i)},this.ws.onclose=n=>{this.logger.info(`ws closed - code: ${n?.code} reason: ${n?.reason}`),e.reject("closed"),t&&(t=!1,this.notifyForSocketState("closed")),this.notifyStatusChanged(!1)},this.ws.onopen=()=>{this.startupTimer.mark("ws-opened"),this.logger.info(`ws opened ${this.settings.identity?.application}`),e.resolve(),t=!0,this.notifyStatusChanged(!0)},this.ws.onmessage=e=>{this._registry.execute("onMessage",e.data)},e.promise}notifyForSocketState(e){this.wsRequests.forEach(t=>{e?t.failed&&t.failed(e):t.callback()}),this.wsRequests=[]}notifyStatusChanged(e,t){this._registry.execute("onConnectedChanged",e,t)}}class ${specs;specsNames=[];messages={};isDone;subs={};subsRefCount={};connection;constructor(e){this.specs={};for(const t of e)this.specs[t.name]=t,this.specsNames.push(t.name)}init(e){this.connection=e;for(const t of this.specsNames)for(const n of this.specs[t].types){let t=this.subsRefCount[n];if(t||(t=0),t+=1,this.subsRefCount[n]=t,t>1)continue;const i=e.on(n,e=>this.processMessage(n,e));this.subs[n]=i}}processMessage(e,t){if(!this.isDone&&t)for(const n of this.specsNames)if(-1!==this.specs[n].types.indexOf(e)){const e=this.messages[n]||[];this.messages[n]=e,e.push(t)}}drain(e,t){t&&(this.messages[e]||[]).forEach(t),delete this.messages[e];for(const t of this.specs[e].types)this.subsRefCount[t]-=1,this.subsRefCount[t]<=0&&(this.connection?.off(this.subs[t]),delete this.subs[t],delete this.subsRefCount[t]);delete this.specs[e],this.specs.length||(this.isDone=!0)}}let W=(e=21)=>{let t="",n=0|e;for(;n--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[64*Math.random()|0];return t};const D=(e,t,n)=>new Promise((i,r)=>{const o=setTimeout(()=>{r(n||`Promise timeout hit: ${t}`)},t);new Promise(e).then(e=>{clearTimeout(o),i(e)}).catch(e=>{clearTimeout(o),r(e)})});class F{settings;logger;identity;isPreferredActivated;_connectionProtocolVersion;_communicationId;publicWindowId;selfAssignedWindowId;iAmConnected=!1;parentReady=!1;rejected=!1;parentPingResolve;parentPingInterval;connectionResolve;extConnectionResolve;extConnectionReject;connectionReject;port;myClientId;extContentAvailable=!1;extContentConnecting=!1;extContentConnected=!1;parentWindowId;parentInExtMode=!1;webNamespace="g42_core_web";parent;parentType;parentPingTimeout=5e3;connectionRequestTimeout=7e3;defaultTargetString="*";registry=k();messages={connectionAccepted:{name:"connectionAccepted",handle:this.handleConnectionAccepted.bind(this)},connectionRejected:{name:"connectionRejected",handle:this.handleConnectionRejected.bind(this)},connectionRequest:{name:"connectionRequest",handle:this.handleConnectionRequest.bind(this)},parentReady:{name:"parentReady",handle:()=>{}},parentPing:{name:"parentPing",handle:this.handleParentPing.bind(this)},platformPing:{name:"platformPing",handle:this.handlePlatformPing.bind(this)},platformReady:{name:"platformReady",handle:this.handlePlatformReady.bind(this)},clientUnload:{name:"clientUnload",handle:()=>{}},manualUnload:{name:"manualUnload",handle:this.handleManualUnload.bind(this)},extConnectionResponse:{name:"extConnectionResponse",handle:this.handleExtConnectionResponse.bind(this)},extSetupRequest:{name:"extSetupRequest",handle:this.handleExtSetupRequest.bind(this)},gatewayDisconnect:{name:"gatewayDisconnect",handle:this.handleGatewayDisconnect.bind(this)},gatewayInternalConnect:{name:"gatewayInternalConnect",handle:this.handleGatewayInternalConnect.bind(this)}};constructor(e,t,n){this.settings=e,this.logger=t,this.identity=n,this.extContentAvailable=!!window.glue42ext,this.setUpMessageListener(),this.setUpUnload(),this.setupPlatformUnloadListener(),this.parentType=window.name.includes("#wsp")?"workspace":void 0}manualSetReadyState(){this.iAmConnected=!0,this.parentReady=!0}get transportWindowId(){return this.publicWindowId}get communicationId(){return this._communicationId}async sendObject(e){if(this.extContentConnected)return window.postMessage({glue42ExtOut:e},window.origin);if(!this.port)throw new Error("Cannot send message, because the port was not opened yet");this.port.postMessage(e)}get isObjectBasedTransport(){return!0}onMessage(e){return this.registry.add("onMessage",e)}send(){return Promise.reject("not supported")}onConnectedChanged(e){return this.registry.add("onConnectedChanged",e)}async open(){this.logger.debug("opening a connection to the web platform gateway."),await this.connect(),this.notifyStatusChanged(!0)}close(){const e={glue42core:{type:this.messages.gatewayDisconnect.name,data:{clientId:this.myClientId,ownWindowId:this.identity?.windowId}}};return this.port?.postMessage(e),this.parentReady=!1,this.notifyStatusChanged(!1,"manual reconnection"),Promise.resolve()}name(){return"web-platform"}async reconnect(){return await this.close(),Promise.resolve()}initiateInternalConnection(){return new Promise((e,t)=>{this.logger.debug("opening an internal web platform connection"),this.port=this.settings.port,this.iAmConnected?this.logger.warn("cannot open a new connection, because this client is currently connected"):(this.port.onmessage=n=>{if(this.iAmConnected&&!n.data?.glue42core)return void this.registry.execute("onMessage",n.data);const i=n.data?.glue42core;i&&(i.type===this.messages.gatewayInternalConnect.name&&i.success&&(this.publicWindowId=this.settings.windowId,this.identity&&this.publicWindowId&&(this.identity.windowId=this.publicWindowId,this.identity.instance=this.publicWindowId),e()),i.type===this.messages.gatewayInternalConnect.name&&i.error&&t(i.error))},this.port.postMessage({glue42core:{type:this.messages.gatewayInternalConnect.name}}))})}initiateRemoteConnection(e){return D((t,n)=>{this.connectionResolve=t,this.connectionReject=n,this.myClientId=this.myClientId??W(10);const i=this.getMyWindowId()||W(10),r={glue42core:{type:this.messages.connectionRequest.name,clientId:this.myClientId,clientType:"child",bridgeInstanceId:i,selfAssignedWindowId:this.selfAssignedWindowId}};if(this.logger.debug("sending connection request"),this.extContentConnecting)return r.glue42core.clientType="child",r.glue42core.bridgeInstanceId=this.myClientId,r.glue42core.parentWindowId=this.parentWindowId,window.postMessage(r,window.origin);if(!e)throw new Error("Cannot send a connection request, because no glue target was specified!");e.postMessage(r,this.defaultTargetString)},this.connectionRequestTimeout,"The connection to the target glue window timed out")}async isParentCheckSuccess(e){try{return await e,{success:!0}}catch(e){return{success:!1}}}setUpMessageListener(){this.settings.port?this.logger.debug("skipping generic message listener, because this is an internal client"):window.addEventListener("message",e=>{const t=e.data?.glue42core;if(!t||this.rejected)return;const n=this.settings.allowedOrigins||[];if(n.length&&!n.includes(e.origin))return void this.logger.warn(`received a message from an origin which is not in the allowed list: ${e.origin}`);if(!this.checkMessageTypeValid(t.type))return void this.logger.error(`cannot handle the incoming glue42 core message, because the type is invalid: ${t.type}`);const i=t.type;this.logger.debug(`received valid glue42core message of type: ${i}`),this.messages[i].handle(e)})}setUpUnload(){this.settings.port?this.logger.debug("skipping unload event listener, because this is an internal client"):(window.addEventListener("beforeunload",()=>{this._connectionProtocolVersion||this.signalClientDisappearing()}),window.addEventListener("pagehide",()=>{this._connectionProtocolVersion&&this.signalClientDisappearing()}))}signalClientDisappearing(){if(this.extContentConnected)return;const e={glue42core:{type:this.messages.clientUnload.name,data:{clientId:this.myClientId,ownWindowId:this.identity?.windowId}}};this.parent?.postMessage(e,this.defaultTargetString),this.port?.postMessage(e)}handlePlatformReady(e){this.logger.debug("the web platform gave the ready signal"),this.parentReady=!0,this.parentPingResolve&&(this.parentPingResolve(),delete this.parentPingResolve),this.parentPingInterval&&(clearInterval(this.parentPingInterval),delete this.parentPingInterval),this.parent=e.source,this.parentType=window.name.includes("#wsp")?"workspace":"window"}handleConnectionAccepted(e){const t=e.data?.glue42core;return this.myClientId!==t.clientId?this.logger?.debug(`ignoring a connection accepted signal, because it is not targeted at me. My id: ${this.myClientId}, the id in the message: ${t.clientId}`):this.handleAcceptanceOfMyRequest(t)}handleAcceptanceOfMyRequest(e){if(this.logger.debug("handling a connection accepted signal targeted at me."),this.isPreferredActivated=e.isPreferredActivated,this.extContentConnecting)return this.processExtContentConnection(e);if(e.port){if(this._connectionProtocolVersion=e.connectionProtocolVersion,this.publicWindowId=this.getMyWindowId(),this.identity&&(this.identity.windowId=this.publicWindowId,this.identity.instance=this.identity.instance?this.identity.instance:this.publicWindowId||W(10)),this.identity&&e.appName&&(this.identity.application=e.appName,this.identity.applicationName=e.appName),this._communicationId=e.communicationId,this.port=e.port,this.port.onmessage=e=>this.registry.execute("onMessage",e.data),this.connectionResolve)return this.logger.debug("my connection is set up, calling the connection resolve."),this.connectionResolve(),void delete this.connectionResolve;this.logger.error("unable to call the connection resolve, because no connection promise was found")}else this.logger.error("cannot set up my connection, because I was not provided with a port")}processExtContentConnection(e){if(this.logger.debug("handling a connection accepted signal targeted at me for extension content connection."),this.extContentConnecting=!1,this.extContentConnected=!0,this.publicWindowId=this.parentWindowId||this.myClientId,this.extContentConnecting&&this.identity&&(this.identity.windowId=this.publicWindowId),this.identity&&e.appName&&(this.identity.application=e.appName,this.identity.applicationName=e.appName),window.addEventListener("message",e=>{const t=e.data?.glue42ExtInc;if(!t)return;const n=this.settings.allowedOrigins||[];!n.length||n.includes(e.origin)?this.registry.execute("onMessage",t):this.logger.warn(`received a message from an origin which is not in the allowed list: ${e.origin}`)}),this.connectionResolve)return this.logger.debug("my connection is set up, calling the connection resolve."),this.connectionResolve(),void delete this.connectionResolve}handleConnectionRejected(e){if(this.logger.debug("handling a connection rejection. Most likely the reason is that this window was not created by a glue API call"),!this.connectionReject)return;const t="string"==typeof e.data.glue42core?.error?`Connection was rejected. ${e.data.glue42core?.error}`:"The platform connection was rejected. Most likely because this window was not created by a glue API call";this.connectionReject(t),delete this.connectionReject}handleConnectionRequest(){this.extContentConnecting&&this.logger.debug("This connection request event is targeted at the extension content")}handleParentPing(e){if(!this.parentReady)return void this.logger.debug("my parent is not ready, I am ignoring the parent ping");if(!this.iAmConnected)return void this.logger.debug("i am not fully connected yet, I am ignoring the parent ping");const t={glue42core:{type:this.messages.parentReady.name}};this.extContentConnected&&(t.glue42core.extMode={windowId:this.myClientId});const n=e.source;this.logger.debug("responding to a parent ping with a ready message"),n.postMessage(t,e.origin)}setupPlatformUnloadListener(){this.onMessage(e=>{"platformUnload"===e.type&&(this.logger.debug("detected a web platform unload"),this.parentReady=!1,this.notifyStatusChanged(!1,"Gateway unloaded"))})}handleManualUnload(){const e={glue42core:{type:this.messages.clientUnload.name,data:{clientId:this.myClientId,ownWindowId:this.identity?.windowId}}};if(this.extContentConnected)return window.postMessage({glue42ExtOut:e},window.origin);this.port?.postMessage(e)}handlePlatformPing(){}notifyStatusChanged(e,t){this.iAmConnected=e,this.registry.execute("onConnectedChanged",e,t)}checkMessageTypeValid(e){return"string"==typeof e&&!!this.messages[e]}requestConnectionPermissionFromExt(){return this.waitForContentScript().then(()=>D((e,t)=>{this.extConnectionResolve=e,this.extConnectionReject=t;this.logger.debug("permission request to the extension content script was sent"),window.postMessage({glue42core:{type:"extSetupRequest"}},window.origin)},this.parentPingTimeout,"Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection timed out"))}handleExtConnectionResponse(e){const t=e.data?.glue42core;if(!t.approved)return this.extConnectionReject?this.extConnectionReject("Cannot initialize glue, because this app was not opened or created by a Glue Client and the request for extension connection was rejected"):void 0;this.extConnectionResolve&&(this.extConnectionResolve(),delete this.extConnectionResolve),this.extContentConnecting=!0,this.parentType="extension",this.logger.debug("The extension connection was approved, proceeding.")}handleExtSetupRequest(){}handleGatewayDisconnect(){}handleGatewayInternalConnect(){}waitForContentScript(){return!!window.glue42ext?.content?Promise.resolve():D(e=>{window.addEventListener("Glue42EXTReady",()=>{e()})},this.connectionRequestTimeout,"The content script was available, but was never heard to be ready")}async connect(){if(this.settings.port)return await this.initiateInternalConnection(),void this.logger.debug("internal web platform connection completed");this.logger.debug("opening a client web platform connection"),await this.findParent(),await this.initiateRemoteConnection(this.parent),this.logger.debug("the client is connected")}async findParent(){const e="Cannot initiate glue, because this window was not opened or created by a glue client",t=this.getPossibleParentsInWindow(window),n=this.getPossibleParentsOutsideWindow(window.top?.opener,window.top),i=new Set([...t,...n]);if(!i.size&&!this.extContentAvailable)throw new Error(e);if(!i.size&&this.extContentAvailable)return void await this.requestConnectionPermissionFromExt();if((await this.isParentCheckSuccess(this.confirmParent(Array.from(i)))).success)this.logger.debug("The default parent was found!");else{if(!this.extContentAvailable)throw new Error(e);await this.requestConnectionPermissionFromExt()}}getPossibleParentsInWindow(e){return e?.parent&&e!==e.parent?[e.parent,...this.getPossibleParentsInWindow(e.parent)]:[]}getPossibleParentsOutsideWindow(e,t){return e&&t&&e!==t?[e,...this.getPossibleParentsInWindow(e),...this.getPossibleParentsOutsideWindow(e.opener,e)]:[]}confirmParent(e){const t=D(t=>{this.parentPingResolve=t;const n={glue42core:{type:this.messages.platformPing.name}};this.parentPingInterval=setInterval(()=>{e.forEach(e=>{e.postMessage(n,this.defaultTargetString)})},1e3)},this.parentPingTimeout,"Cannot initiate glue, because this window was not opened or created by a glue client");return t.catch(()=>{this.parentPingInterval&&(clearInterval(this.parentPingInterval),delete this.parentPingInterval)}),t}getMyWindowId(){return"workspace"===this.parentType?window.name.substring(0,window.name.indexOf("#wsp")):window===window.top?window.name?.includes("g42")?window.name:(this.selfAssignedWindowId=this.selfAssignedWindowId||`g42-${W(10)}`,this.selfAssignedWindowId):void 0}}class L{minSequenceInterval;queue=[];isExecutingQueue=!1;constructor(e=0){this.minSequenceInterval=e}enqueue(e){return new Promise((t,n)=>{this.queue.push({action:e,resolve:t,reject:n}),this.executeQueue()})}async executeQueue(){if(!this.isExecutingQueue){for(this.isExecutingQueue=!0;this.queue.length;){const e=this.queue.shift();if(!e)return void(this.isExecutingQueue=!1);try{const t=await e.action();e.resolve(t)}catch(t){e.reject(t)}await this.intervalBreak()}this.isExecutingQueue=!1}}intervalBreak(){return new Promise(e=>setTimeout(e,this.minSequenceInterval))}}function G(e,t,n,i,r){null==e&&(e="global"),i=i??["success"],r=r??["error"];let o,s="global"===e,a=!1,c=!1;const d=k();t.disconnected(function(){n.debug("connection is down"),c=!1,s=!1,a=!0,Object.keys(h).forEach(e=>{const t=h[e];t&&(n.trace(`failing pending request ${e} due to connection lost`),t.error({err:"Connection lost - gateway connection was disconnected"}))}),d.execute("onLeft",{disconnected:!0})}),t.loggedIn(async function(){if(c=!0,a){n.debug("connection is now up - trying to reconnect...");try{await l(o)}catch{n.trace("failed to reconnect")}}}),t.on("success",e=>g(e)),t.on("error",e=>p(e)),t.on("result",e=>g(e)),i&&i.forEach(e=>{t.on(e,e=>g(e))}),r&&r.forEach(e=>{t.on(e,e=>p(e))});const h={};function l(t){return o=t,new Promise((i,r)=>{if(s)return void i({});let o;if("global"===e)o=c?Promise.resolve({}):Promise.reject("not connected to gateway");else{n.debug(`joining domain ${e}`);o=y({type:"join",destination:e,domain:"global",options:t})}o.then(()=>{!function(){n.debug("did join "+e),s=!0;const t=a;a=!1,d.execute("onJoined",t)}(),i({})}).catch(t=>{n.debug("error joining "+e+" domain: "+JSON.stringify(t)),r(t)})})}function u(e){return s&&e(!1),d.add("onJoined",e)}function p(t){if(e!==t.domain)return;const n=t.request_id;if(!n)return;const i=h[n];i&&i.error(t)}function g(t){if(t.domain!==e)return;const n=t.request_id;if(!n)return;const i=h[n];i&&i.success(t)}function f(){return W(10)}let m=[];function y(i,r,o){if(i.type&&-1===["hello","join"].indexOf(i.type)&&!s){console.warn(`trying to send a message (${i.domain} ${i.type}) but not connected, will queue`);const e=new M;if(m.push({msg:i,tag:r,options:o,pw:e}),1===m.length){const e=u(()=>{n.info(`joined - will now send queued messages (${m.length} -> [${m.map(e=>e.msg.type)}])`),m.forEach(e=>{y(e.msg,e.tag,e.options).then(t=>e.pw.resolve(t)).catch(t=>e.pw.reject(t))}),m=[],e()})}return e.promise}o=o??{},i.request_id=i.request_id??f(),i.domain=i.domain??e,o.skipPeerId||(i.peer_id=t.peerId);const a=i.request_id;return new Promise((e,n)=>{h[a]={success:t=>{delete h[a],t._tag=r,e(t)},error:e=>{console.warn(`Gateway error - ${JSON.stringify(e)}`),delete h[a],e._tag=r,n(e)}},t.send(i,o).catch(e=>{h[a]?.error({err:e})})})}return{join:l,leave:function(){return"global"===e?Promise.resolve():(n.debug("stopping session "+e+"..."),a=!1,y({type:"leave",destination:e,domain:"global"}).then(()=>{s=!1,d.execute("onLeft")}).catch(()=>{s=!1,d.execute("onLeft")}))},onJoined:u,onLeft:function(e){return s||e(),d.add("onLeft",e)},send:y,sendFireAndForget:function(n){return n.request_id=n.request_id?n.request_id:f(),n.domain=n.domain??e,n.peer_id=t.peerId,t.send(n)},on:(i,r)=>{t.on(i,t=>{if(t.domain===e)try{r(t)}catch(e){n.error(`Callback failed: ${e} \n ${e.stack} \n msg was: ${JSON.stringify(t)}`,e)}})},loggedIn:e=>t.loggedIn(e),connected:e=>t.connected(e),disconnected:e=>t.disconnected(e),get peerId(){return t.peerId},get domain(){return e}}}class U{settings;logger;protocolVersion=3;peerId;token;info;resolvedIdentity;availableDomains;gatewayToken;replayer;messageHandlers={};ids=1;registry=k();_connected=!1;isTrace=!1;transport;_defaultTransport;_defaultAuth;_targetTransport;_targetAuth;_swapTransport=!1;_switchInProgress=!1;_transportSubscriptions=[];datePrefix="#T42_DATE#";datePrefixLen=this.datePrefix.length;dateMinLen=this.datePrefixLen+1;datePrefixFirstChar=this.datePrefix[0];_sequelizer=new L;_isLoggedIn=!1;shouldTryLogin=!0;pingTimer;sessions=[];globalDomain;initialLogin=!0;initialLoginAttempts=3;loginConfig;loginRetryInProgress=!1;constructor(e,t){if(this.settings=e,this.logger=t,(e=e||{}).reconnectAttempts=e.reconnectAttempts??10,e.reconnectInterval=e.reconnectInterval??1e3,e.inproc)this.transport=new x(e.inproc,t.subLogger("inMemory"));else if(e.sharedWorker)this.transport=new E(e.sharedWorker,t.subLogger("shared-worker"));else if(e.webPlatform)this.transport=new F(e.webPlatform,t.subLogger("web-platform"),e.identity);else{if(void 0===e.ws)throw new Error("No connection information specified");this.transport=new j(e,t.subLogger("ws"))}this.isTrace=t.canPublish("trace"),t.debug(`starting with ${this.transport.name()} transport`);const n=this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)),i=this.transport.onMessage(this.handleTransportMessage.bind(this));this._transportSubscriptions.push(n),this._transportSubscriptions.push(i),this._defaultTransport=this.transport,this.ping()}async switchTransport(e){return this._sequelizer.enqueue(async()=>{if(!e||"object"!=typeof e)throw new Error("Cannot switch transports, because the settings are missing or invalid.");if(void 0===e.type)throw new Error("Cannot switch the transport, because the type is not defined");this.logger.trace(`Starting transport switch with settings: ${JSON.stringify(e)}`);const t="secondary"===e.type?this.getNewSecondaryTransport(e):this._defaultTransport;this._targetTransport=t,this._targetAuth="secondary"===e.type?this.getNewSecondaryAuth(e):this._defaultAuth;const n=this.verifyConnection();this._swapTransport=!0,this._switchInProgress=!0,this.logger.trace("The new transport has been set, closing the current transport"),await this.transport.close();try{await n;const e=this.transport===t;return this.logger.info(`The reconnection after the switch was completed. Was the switch a success: ${e}`),this._switchInProgress=!1,{success:e}}catch(e){return this.logger.info("The reconnection after the switch timed out, reverting back to the default transport."),this.switchTransport({type:"default"}),this._switchInProgress=!1,{success:!1}}})}onLibReAnnounced(e){return this.registry.add("libReAnnounced",e)}setLibReAnnounced(e){this.registry.execute("libReAnnounced",e)}send(e,t){if(this.transport.sendObject&&this.transport.isObjectBasedTransport){const n=this.createObjectMessage(e);return this.isTrace&&this.logger.trace(`>> ${JSON.stringify(n)}`),this.transport.sendObject(n,t)}{const n=this.createStringMessage(e);return this.isTrace&&this.logger.trace(`>> ${n}`),this.transport.send(n,t)}}on(e,t){e=e.toLowerCase(),void 0===this.messageHandlers[e]&&(this.messageHandlers[e]={});const n=this.ids++;return this.messageHandlers[e][n]=t,{type:e,id:n}}off(e){delete this.messageHandlers[e.type.toLowerCase()][e.id]}get isConnected(){return this._isLoggedIn}connected(e){return this.loggedIn(()=>{const t=this.transport.name();e(t)})}disconnected(e){return this.registry.add("disconnected",e)}async login(e,t){if(this.logger.debug(`Login initiated - reconnect: ${t}, transport: ${this.transport.name()}`),this._defaultAuth||(this._defaultAuth=e),this._swapTransport){this.logger.trace("Detected a transport swap, swapping transports");e=this.transportSwap()??e}try{await this.transport.open(),this.logger.debug(`Transport: ${this.transport.name()} opened, logging in`),N("connection").mark("transport-opened");const n=await this.loginCore(e,t);return this.logger.debug(`Logged in with identity: ${JSON.stringify(n)}`),N("connection").mark("protocol-logged-in"),n}catch(e){throw this._switchInProgress&&(this.logger.debug("An error while logging in after a transport swap, preparing a default swap."),this.prepareDefaultSwap()),new Error(e)}}async logout(){await this.logoutCore(),await this.transport.close()}loggedIn(e){return this._isLoggedIn&&e(),this.registry.add("onLoggedIn",e)}domain(e,t,n){let i=this.sessions.find(t=>t.domain===e);return i||(i=G(e,this,this.logger.subLogger(`domain=${e}`),t,n),this.sessions.push(i)),i}authToken(){return this.globalDomain?this.globalDomain.send({domain:"global",type:"create-token"}).then(e=>e.token):Promise.reject(new Error("no global domain session"))}reconnect(){return this.transport.reconnect()}setLoggedIn(e){this._isLoggedIn=e,this._isLoggedIn&&(this.initialLogin=!1,this.registry.execute("onLoggedIn"))}distributeMessage(e,t){const n=this.messageHandlers[t.toLowerCase()];void 0!==n&&Object.keys(n).forEach(t=>{const i=n[t];if(void 0!==i)try{i(e)}catch(e){try{this.logger.error(`Message handler failed with ${e.stack}`,e)}catch(t){console.log("Message handler failed",e)}}})}handleConnectionChanged(e){this._connected!==e?(this.logger.info("connection state changed to "+(e?"connected":"disconnected")),this._connected=e,e?(this.settings?.replaySpecs?.length&&(this.replayer=new $(this.settings.replaySpecs),this.replayer.init(this)),this.registry.execute("connected")):(this.setLoggedIn(!1),this.shouldTryLogin&&this.attemptLoginWithRetry(),this.registry.execute("disconnected"))):this.logger.trace("connection state unchanged, skipping")}async attemptLoginWithRetry(){if(!this.loginConfig)throw new Error("no login info");if(this.loginRetryInProgress)this.logger.debug("login attempt already in progress, ignoring request...");else if(this._isLoggedIn)this.logger.debug("already logged in, ignoring request...");else{if(this.initialLogin){if(this.logger.debug(`initial login attempt failed, ${this.initialLoginAttempts} attempts remaining...`),this.initialLoginAttempts<=0)return void this.logger.info("maximum initial login attempts reached, will not try to login again");this.initialLoginAttempts--}try{this.logger.debug(`will try a new login... ${this.loginRetryInProgress}`),this.loginRetryInProgress=!0,await this.login(this.loginConfig,!0)}catch(e){this.logger.error(`error trying to login: ${e?.message}`,e),setTimeout(this.attemptLoginWithRetry.bind(this),this.settings.reconnectInterval??1e3)}finally{this.loginRetryInProgress=!1}}}handleTransportMessage(e){let t;t="string"==typeof e?this.processStringMessage(e):this.processObjectMessage(e),this.isTrace&&this.logger.trace(`<< ${JSON.stringify(t)}`),this.distributeMessage(t.msg,t.msgType)}verifyConnection(){return D(e=>{let t;const n=((e,t)=>{let n=e;return()=>{n--,0===n&&t()}})(2,()=>{t&&t(),e()});t=this.onLibReAnnounced(e=>"interop"===e.name||"contexts"===e.name?n():void 0)},1e4,"Transport switch timed out waiting for all libraries to be re-announced")}getNewSecondaryTransport(e){if(!e.transportConfig?.url)throw new Error("Missing secondary transport URL.");return new j(Object.assign({},this.settings,{ws:e.transportConfig.url,reconnectAttempts:1}),this.logger.subLogger("ws-secondary"))}getNewSecondaryAuth(e){if(!e.transportConfig?.auth)throw new Error("Missing secondary transport auth information.");return e.transportConfig.auth}transportSwap(){if(this._swapTransport=!1,!this._targetTransport||!this._targetAuth)return void this.logger.warn(`Error while switching transports - either the target transport or auth is not defined: transport defined -> ${!!this._defaultTransport}, auth defined -> ${!!this._targetAuth}. Staying on the current one.`);this._transportSubscriptions.forEach(e=>e()),this._transportSubscriptions=[],this.transport=this._targetTransport;const e=this.transport.onConnectedChanged(this.handleConnectionChanged.bind(this)),t=this.transport.onMessage(this.handleTransportMessage.bind(this));return this._transportSubscriptions.push(e),this._transportSubscriptions.push(t),this._targetAuth}prepareDefaultSwap(){this._transportSubscriptions.forEach(e=>e()),this._transportSubscriptions=[],this.transport.close().catch(e=>this.logger.warn(`Error closing the ${this.transport.name()} transport after a failed connection attempt: ${JSON.stringify(e)}`)),this._targetTransport=this._defaultTransport,this._targetAuth=this._defaultAuth,this._swapTransport=!0}processStringMessage(e){const t=JSON.parse(e,(e,t)=>{if("string"!=typeof t)return t;if(t.length<this.dateMinLen)return t;if(!t.startsWith(this.datePrefixFirstChar))return t;if(t.substring(0,this.datePrefixLen)!==this.datePrefix)return t;try{const e=parseInt(t.substring(this.datePrefixLen,t.length),10);return isNaN(e)?t:new Date(e)}catch(e){return t}});return{msg:t,msgType:t.type}}createStringMessage(e){const t=Date.prototype.toJSON;try{const t=this.datePrefix;Date.prototype.toJSON=function(){return t+this.getTime()};return JSON.stringify(e)}finally{Date.prototype.toJSON=t}}processObjectMessage(e){if(!e.type)throw new Error("Object should have type property");return{msg:e,msgType:e.type}}createObjectMessage(e){return e}async loginCore(e,t){this.loginConfig=e,this.loginConfig||(this.loginConfig={username:"",password:""}),this.shouldTryLogin=!0;const n=await this.setupAuthConfig(e,t),i={type:"hello",identity:this.settings.identity,authentication:n};e.sessionId&&(i.request_id=e.sessionId),this.globalDomain||(this.globalDomain=G("global",this,this.logger.subLogger("global-domain"),["welcome","token","authentication-request"]));const r={skipPeerId:!0};this.initialLogin&&(r.retryInterval=this.settings.reconnectInterval,r.maxRetries=this.settings.reconnectAttempts);try{const t=await this.tryAuthenticate(this.globalDomain,i,r,e);return this.logger.info("login successful with peerId "+t.peer_id),this.peerId=t.peer_id,this.resolvedIdentity=t.resolved_identity,this.availableDomains=t.available_domains,t.options&&(this.token=t.options.access_token,this.info=t.options.info),this.setLoggedIn(!0),t.resolved_identity}catch(e){throw this.logger.error("error sending hello message - "+(e.message||e.msg||e.reason||e),e),e}finally{e?.flowCallback&&e.sessionId&&e.flowCallback(e.sessionId,null)}}async tryAuthenticate(e,t,n,i){let r;for(;;){const o=await e.send(t,void 0,n);if("authentication-request"!==o.type){if("welcome"===o.type){r=o;break}throw"error"===o.type?new Error("Authentication failed: "+o.reason):new Error("Unexpected message type during authentication: "+o.type)}{const e=Buffer.from(o.authentication.token,"base64");i.flowCallback&&i.sessionId&&(t.authentication.token=(await i.flowCallback(i.sessionId,e)).data.toString("base64")),t.request_id=i.sessionId}}return r}async setupAuthConfig(e,t){const n={};if(this.gatewayToken=e.gatewayToken,e.gatewayToken){if(t)try{e.gatewayToken=await this.getNewGWToken()}catch(e){this.logger.warn(`failed to get GW token when reconnecting ${e?.message||e}`)}n.method="gateway-token",n.token=e.gatewayToken,this.gatewayToken=e.gatewayToken}else if("sspi"===e.flowName){if(n.provider="win",n.method="access-token",!e.flowCallback||!e.sessionId)throw new Error("Invalid SSPI config");n.token=(await e.flowCallback(e.sessionId,null)).data.toString("base64")}else if(e.token)n.method="access-token",n.token=e.token;else if(e.username)n.method="secret",n.login=e.username,n.secret=e.password;else{if(!e.provider)throw new Error("invalid auth message"+JSON.stringify(e));n.provider=e.provider,n.providerContext=e.providerContext}return n}async logoutCore(){this.logger.debug("logging out..."),this.shouldTryLogin=!1,this.pingTimer&&clearTimeout(this.pingTimer);const e=this.sessions.map(e=>e.leave());await Promise.all(e)}getNewGWToken(){if("undefined"!=typeof window){const e=window.glue42gd;if(e)return e.getGWToken()}return Promise.reject(new Error("not running in GD"))}ping(){this.shouldTryLogin&&(this._isLoggedIn&&this.send({type:"ping"}),this.pingTimer=setTimeout(()=>{this.ping()},3e4))}}const H=["trace","debug","info","warn","error","off"];let B=class e{name;parent;static Interop;static InteropMethodName="T42.AppLogger.Log";static Instance;path;subLoggers=[];_consoleLevel;_publishLevel;loggerFullName;includeTimeAndLevel;logFn=console;customLogFn=!1;constructor(e,t,n){this.name=e,this.parent=t,this.name=e,this.path=t?`${t.path}.${e}`:e,this.loggerFullName=`[${this.path}]`,this.includeTimeAndLevel=!n,n&&(this.logFn=n,this.customLogFn=!0)}subLogger(t){const n=this.subLoggers.filter(e=>e.name===t)[0];if(void 0!==n)return n;Object.keys(this).forEach(e=>{if(e===t)throw new Error("This sub logger name is not allowed.")});const i=new e(t,this,this.customLogFn?this.logFn:void 0);return this.subLoggers.push(i),i}publishLevel(e){return e&&(this._publishLevel=e),this._publishLevel||this.parent?.publishLevel()}consoleLevel(e){return e&&(this._consoleLevel=e),this._consoleLevel||this.parent?.consoleLevel()}log(e,t,n){this.publishMessage(t||"info",e,n)}trace(e){this.log(e,"trace")}debug(e){this.log(e,"debug")}info(e){this.log(e,"info")}warn(e){this.log(e,"warn")}error(e,t){this.log(e,"error",t)}canPublish(e,t){return H.indexOf(e)>=H.indexOf(t||this.consoleLevel()||"trace")}publishMessage(t,n,i){const r=this.loggerFullName;if("error"===t&&!i){const e=new Error;e.stack&&(n=n+"\n"+e.stack.split("\n").slice(4).join("\n"))}if(this.canPublish(t,this.publishLevel())){const o=e.Interop;if(o)try{if(o.methods({name:e.InteropMethodName}).length>0){const s={msg:n,logger:r,level:t};i&&i instanceof Error&&(s.error={message:i.message,stack:i.stack??""}),o.invoke(e.InteropMethodName,s).catch(e=>{this.logFn.error(`Unable to send log message to the platform: ${e.message}`,e)})}}catch{}}if(this.canPublish(t)){let e="";if(this.includeTimeAndLevel){const n=new Date;e=`[${`${n.getHours()}:${n.getMinutes()}:${n.getSeconds()}:${n.getMilliseconds()}`}] [${t}] `}const o=`${e}${r}: ${n}`;switch(t){case"trace":this.logFn.debug(o);break;case"debug":this.logFn.debug?this.logFn.debug(o):this.logFn.log(o);break;case"info":this.logFn.info(o);break;case"warn":this.logFn.warn(o);break;case"error":i?this.logFn.error(o,i):this.logFn.error(o)}}}};const J="create-context",q="created",V="destroyed",z="context-created",K="context-added",Q="subscribe-context",Z="subscribed-context",X="unsubscribe-context",Y="destroy-context",ee="context-destroyed",te="update-context",ne="context-updated",ie="joined",re={get name(){return"context"},get types(){return[J,q,V,z,K,Q,Z,X,Y,ee,te,ne,ie]}};var oe="6.7.3";class se{name;contextId;context;isAnnounced;createdByUs;joinedActivity;updateCallbacks={};activityId;sentExplicitSubscription;get hasReceivedSnapshot(){return this.snapshotPromiseWrapper.resolved}set hasReceivedSnapshot(e){e?this.snapshotPromiseWrapper.resolve():this.snapshotPromiseWrapper=new M}get snapshotPromise(){return this.snapshotPromiseWrapper.promise}snapshotPromiseWrapper;constructor(e,t,n,i){this.contextId=e,this.name=t,this.isAnnounced=n,this.activityId=i,this.context={},this.snapshotPromiseWrapper=new M}hasCallbacks(){return Object.keys(this.updateCallbacks).length>0}getState(){return this.isAnnounced&&this.hasCallba