UNPKG

@interopio/core

Version:

IOConnect core library

1 lines 125 kB
!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).core=e.core||{},e.core.min=t())}(this,(function(){"use strict";var e={STRING:1,NUMBER:2,TIMESTAMP:3,OBJECT:4};function t(t){return t.type===e.TIMESTAMP?"timestamp":t.type===e.NUMBER?"number":t.type===e.STRING?"string":t.type===e.OBJECT?"object":"unknown"}function n(e){return e.constructor===Date?"timestamp":"number"==typeof e?"number":"string"==typeof e?"string":"object"==typeof e?"object":"string"}function s(e){const s={},o=t(e);if("object"===o){const t=Object.keys(e.value).reduce(((t,s)=>{const r=n(e.value[s]);if("object"===r){const n=i(e.value[s]);t[s]={type:"object",description:"",context:{},composite:n}}else t[s]={type:r,description:"",context:{}};return t}),{});s.composite=t}return s.name=r(e.path.join("/")+"/"+e.name),s.type=o,s.description=e.description,s.context={},s}function i(e){return Object.keys(e).reduce(((t,s)=>{const r=n(e[s]);return t[s]="object"===r?{type:"object",description:"",context:{},composite:i(e[s])}:{type:r,description:"",context:{}},t}),{})}function r(e){return void 0!==e&&e.length>0&&"/"!==e[0]?"/"+e:e}function o(e){return"timestamp"===t(e)?Date.now():a(e.value)}function a(e){return"object"!=typeof e?e:Object.keys(e).reduce(((t,n)=>{const s=e[n];return"object"==typeof s&&s.constructor!==Date?t[n]=a(s):s.constructor===Date?t[n]=new Date(s).getTime():s.constructor===Boolean?t[n]=s.toString():t[n]=s,t}),{})}function c(e){return e.reduce(((e,t)=>e.concat(Array.isArray(t)?c(t):t)),[])}function d(e){const t=c(e.root.getAggregateState()),n=t.sort(((e,t)=>e.state?t.state?t.state-e.state:-1:1))[0];const s=function(e){let t="";return e.forEach(((e,n,s)=>{const i=e.path.join(".");n===s.length-1?t+=i+"."+e.name+": "+e.description:t+=i+"."+e.name+": "+e.description+","})),t.length>100?t.slice(0,100)+"...":t}(t);return{description:s,value:n.state}}var h=(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 u{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,s,i){this.definition=e,this.system=t,this.transport=n,this.value=s,this.type=i,h(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 l extends u{constructor(t,n,s,i){super(t,n,s,i,e.NUMBER)}incrementBy(e){this.update(this.value+e)}increment(){this.incrementBy(1)}decrement(){this.incrementBy(-1)}decrementBy(e){this.incrementBy(-1*e)}}class p extends u{constructor(t,n,s,i){super(t,n,s,i,e.OBJECT)}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 g extends u{constructor(t,n,s,i){super(t,n,s,i,e.STRING)}}class m extends u{constructor(t,n,s,i){super(t,n,s,i,e.TIMESTAMP)}now(){this.update(new Date)}}function f(t,n,s,i,r){if(!n)throw new Error("Repository is required");if(!s)throw new Error("Transport is required");const o=s,a=t,c=r||"",d=n,h=i,u=function e(t){if(!t||!t.parent)return[];const n=e(t.parent);return n.push(t.name),n}(i);let b={};const y=(w="/",((v=u)&&v.length>0?v.join(w):"")+t);var v,w;const _=n.root,S=[],I=[];function x(e,t,n,s){let i={name:""};i="string"==typeof e?{name:e}:e;const r=I.filter((e=>e.name===i.name));if(r.length>0){const e=r[0];if(e.type!==t)throw new Error(`A metric named ${i.name} is already defined with different type.`);return void 0!==n&&e.update(n).catch((()=>{})),e}const o=s(i);return I.push(o),o}const C={get name(){return a},get description(){return c},get repo(){return d},get parent(){return h},path:u,id:y,root:_,get subSystems(){return S},get metrics(){return I},subSystem:function(e,t){if(!e||0===e.length)throw new Error("name is required");const n=S.filter((t=>t.name===e));if(n.length>0)return n[0];const s=f(e,d,o,C,t);return S.push(s),s},getState:()=>b,setState:function(e,t){b={state:e,description:t},o.updateSystem(C,b)},stringMetric:function(t,n){return x(t,e.STRING,n,(e=>new g(e,C,o,n)))},timestampMetric:function(t,n){return x(t,e.TIMESTAMP,n,(e=>new m(e,C,o,n)))},objectMetric:function(t,n){return x(t,e.OBJECT,n,(e=>new p(e,C,o,n)))},numberMetric:function(t,n){return x(t,e.NUMBER,n,(e=>new l(e,C,o,n)))},getAggregateState:function(){const e=[];return Object.keys(b).length>0&&e.push({name:a,path:u,state:b.state,description:b.description}),S.forEach((t=>{const n=t.getAggregateState();n.length>0&&e.push(...n)})),e}};return o.createSystem(C),C}class b{root;constructor(e,t){t.init(this),this.root=f("",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,s=n?n.getAttribute("class")??"":"";t.objectMetric("LastBrowserEvent",{type:"click",timestamp:new Date,target:{className:s,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",""),s=e.stringMetric("AppName","");if("undefined"!=typeof window){if(void 0!==window.location){const e=window.location.href;n.update(e)}void 0!==window.glue42gd&&s.update(window.glue42gd.appName)}}}class y{init(e){}createSystem(e){return Promise.resolve()}updateSystem(e,t){return Promise.resolve()}createMetric(e){return Promise.resolve()}updateMetric(e){return Promise.resolve()}}class v{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 w=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 a=e=>{c(e.root)},c=e=>{h(e),e.metrics.forEach((e=>{u(e)})),e.subSystems.forEach((e=>{c(e)}))},h=async e=>{if(void 0===e.parent)return;await n;const t={type:"define",metrics:[{name:r(e.path.join("/")+"/"+e.name+"/State"),type:"object",composite:{Description:{type:"string",description:""},Value:{type:"number",description:""}},description:"System state",context:{}}]};i.send(t)},u=async e=>{const t=p(e);await n;const r={type:"define",metrics:[s(t)]};i.send(r),void 0!==t.value&&l(t)},l=e=>{if(g()){const t=o(e),n={type:"publish",values:[{name:r(e.path.join("/")+"/"+e.name),value:t,timestamp:Date.now()}]};return i.sendFireAndForget(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:s=>{let r;n=new Promise((e=>{r=e})),i=e.domain("metrics"),i.onJoined((e=>{!e&&r&&(r(),r=void 0);const t={type:"define",metrics:[{name:"/State",type:"object",composite:{Description:{type:"string",description:""},Value:{type:"number",description:""}},description:"System state",context:{}}]};i.send(t),e&&a(s)})),i.join({system:t.system,service:t.service,instance:t.instance})},createSystem:h,updateSystem:async(t,s)=>{await n;const o={type:"publish",values:[{name:r(t.path.join("/")+"/"+t.name+"/State"),value:{Description:s.description,Value:s.state},timestamp:Date.now()}]};i.send(o);const a=d(t),c={type:"publish",peer_id:e.peerId,values:[{name:"/State",value:{Description:a.description,Value:a.value},timestamp:Date.now()}]};i.send(c)},createMetric:u,updateMetric:async e=>{const t=p(e);await n,l(t)}}}(e.connection,e):new y;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 s;const i=(e,i,r)=>{if(void 0===e||""===e)throw new Error("name is mandatory");if(void 0===i||""===i)throw new Error("action is mandatory");if(void 0===r||""===r)throw new Error("payload is mandatory");s?s.update({name:e,action:i,payload:r}):s=t.objectMetric(n,{name:e,action:i,payload:r})};return e.featureMetric=i,e}(n);return function(e,t){if("undefined"==typeof window)return;const n=window?.glue42gd?.metrics?.pagePerformanceMetrics;n&&(t=n);t?.enabled&&new v(e,t.initialPublishTimeout,t.publishInterval)}(i,e.pagePerformanceMetrics),i};var _="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function S(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function I(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 s(n,s){var i=n instanceof Error?n:new Error(n);if(t)t(i);else{var r='[ERROR] callback-registry: User callback for key "'+s+'" failed: '+i.stack;if(e)switch(e.errorHandling){case"log":return console.error(r);case"silent":return;case"throw":throw new Error(r)}console.error(r)}}return{add:function(e,t,i){var r=n[e];return r||(r=[],n[e]=r),r.push(t),i&&setTimeout((function(){i.forEach((function(i){var r;if(null===(r=n[e])||void 0===r?void 0:r.includes(t))try{Array.isArray(i)?t.apply(void 0,i):t.apply(void 0,[i])}catch(t){s(t,e)}}))}),0),function(){var s=n[e];s&&(0===(s=s.reduce((function(e,n,s){return n===t&&e.length===s||e.push(n),e}),[])).length?delete n[e]:n[e]=s)}},execute:function(e){for(var t=[],i=1;i<arguments.length;i++)t[i-1]=arguments[i];var r=n[e];if(!r||0===r.length)return[];var o=[];return r.forEach((function(n){try{var i=n.apply(void 0,t);o.push(i)}catch(t){o.push(void 0),s(t,e)}})),o},clear:function(){n={}},clearKey:function(e){n[e]&&delete n[e]}}}I.default=I;var x=S(I);class C{gw;registry=x();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 T{logger;worker;registry=x();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)}}class k{static isNode(){if(void 0!==k._isNode)return k._isNode;if("undefined"!=typeof window)return k._isNode=!1,!1;try{k._isNode="[object process]"===Object.prototype.toString.call(global.process)}catch(e){k._isNode=!1}return k._isNode}static _isNode}class M{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 j={};function P(e){const t=j[e];if(t)return t;const n=[];function s(){return(new Date).getTime()}const i=s();let r,o;function a(e,t){const i=t??s();let r=0;n.length>0&&(r=i-n[n.length-1].time),n.push({name:e,time:i,diff:r})}a("start",i);const c={get startTime(){return i},get endTime(){return r},get period(){return o},stop:function(){return r=s(),a("end",r),o=r-i,o},mark:a,marks:n};return j[e]=c,c}const A=k.isNode()?require("ws"):window.WebSocket;class R{ws;logger;settings;startupTimer=P("connection");_running=!0;_registry=x();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;return this.logger.debug(`initiating ws to ${this.settings.ws}...`),this.ws=new A(this.settings.ws??""),this.ws.onerror=t=>{let n="";try{n=JSON.stringify(t)}catch(e){const s=new WeakSet,i=(e,t)=>{if("object"==typeof t&&null!==t){if(s.has(t))return;s.add(t)}return t};n=JSON.stringify(t,i)}this.logger.info(`ws error - reason: ${n}`),e.reject("error"),this.notifyStatusChanged(!1,n)},this.ws.onclose=t=>{this.logger.info(`ws closed - code: ${t?.code} reason: ${t?.reason}`),e.reject("closed"),this.notifyStatusChanged(!1)},this.ws.onopen=()=>{this.startupTimer.mark("ws-opened"),this.logger.info(`ws opened ${this.settings.identity?.application}`),e.resolve(),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 E{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 s=e.on(n,(e=>this.processMessage(n,e)));this.subs[n]=s}}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 O=(e=21)=>{let t="",n=e;for(;n--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[64*Math.random()|0];return t};const N=(e,t,n)=>new Promise(((s,i)=>{const r=setTimeout((()=>{i(n||`Promise timeout hit: ${t}`)}),t);new Promise(e).then((e=>{clearTimeout(r),s(e)})).catch((e=>{clearTimeout(r),i(e)}))}));class L{settings;logger;identity;isPreferredActivated;_communicationId;publicWindowId;selfAssignedWindowId;iAmConnected=!1;parentReady=!1;rejected=!1;parentPingResolve;parentPingInterval;connectionResolve;extConnectionResolve;extConnectionReject;connectionReject;port;myClientId;children=[];extContentAvailable=!1;extContentConnecting=!1;extContentConnected=!1;parentWindowId;parentInExtMode=!1;webNamespace="g42_core_web";parent;parentType;parentPingTimeout=5e3;connectionRequestTimeout=7e3;defaultTargetString="*";registry=x();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:this.handleClientUnload.bind(this)},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},this.defaultTargetString);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 s=n.data?.glue42core;s&&(s.type===this.messages.gatewayInternalConnect.name&&s.success&&(this.publicWindowId=this.settings.windowId,this.identity&&this.publicWindowId&&(this.identity.windowId=this.publicWindowId,this.identity.instance=this.publicWindowId),e()),s.type===this.messages.gatewayInternalConnect.name&&s.error&&t(s.error))},this.port.postMessage({glue42core:{type:this.messages.gatewayInternalConnect.name}}))}))}initiateRemoteConnection(e){return N(((t,n)=>{this.connectionResolve=t,this.connectionReject=n,this.myClientId=this.myClientId??O(10);const s=this.getMyWindowId()||O(10),i={glue42core:{type:this.messages.connectionRequest.name,clientId:this.myClientId,clientType:"child",bridgeInstanceId:s,selfAssignedWindowId:this.selfAssignedWindowId}};if(this.logger.debug("sending connection request"),this.extContentConnecting)return i.glue42core.clientType="child",i.glue42core.bridgeInstanceId=this.myClientId,i.glue42core.parentWindowId=this.parentWindowId,window.postMessage(i,this.defaultTargetString);if(!e)throw new Error("Cannot send a connection request, because no glue target was specified!");e.postMessage(i,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 s=t.type;this.logger.debug(`received valid glue42core message of type: ${s}`),this.messages[s].handle(e)}))}setUpUnload(){this.settings.port?this.logger.debug("skipping unload event listener, because this is an internal client"):window.addEventListener("beforeunload",(()=>{if(this.extContentConnected)return;const e={glue42core:{type:this.messages.clientUnload.name,data:{clientId:this.myClientId,ownWindowId:this.identity?.windowId}}};this.parent&&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.handleAcceptanceOfMyRequest(t):this.handleAcceptanceOfGrandChildRequest(t,e)}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.publicWindowId=this.getMyWindowId(),this.identity&&(this.identity.windowId=this.publicWindowId,this.identity.instance=this.identity.instance?this.identity.instance:this.publicWindowId||O(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}handleAcceptanceOfGrandChildRequest(e,t){if(this.extContentConnecting||this.extContentConnected)return void this.logger.debug("cannot process acceptance of a grandchild, because I am connected to a content script");this.logger.debug(`handling a connection accepted signal targeted at a grandchild: ${e.clientId}`);const n=this.children.find((t=>t.grandChildId===e.clientId));n?(n.connected=!0,this.logger.debug(`the grandchild connection for ${e.clientId} is set up, forwarding the success message and the gateway port`),e.parentWindowId=this.publicWindowId,n.source.postMessage(t.data,n.origin,[e.port])):this.logger.error(`cannot handle connection accepted for grandchild: ${e.clientId}, because there is no grandchild with this id`)}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(e){if(this.extContentConnecting)return void this.logger.debug("This connection request event is targeted at the extension content");const t=e.source,n=e.data.glue42core;return n.clientType&&"grandChild"===n.clientType?n.clientId?this.parent?(this.logger.debug(`handling a connection request for a grandchild: ${n.clientId}`),this.children.push({grandChildId:n.clientId,source:t,connected:!1,origin:e.origin}),this.logger.debug(`grandchild: ${n.clientId} is prepared, forwarding connection request to the platform`),void this.parent.postMessage(e.data,this.defaultTargetString)):this.rejectConnectionRequest(t,e.origin,"Cannot forward the connection request, because no direct connection to the platform was found"):this.rejectConnectionRequest(t,e.origin,"rejecting a connection request, because the source did not provide a valid id"):this.rejectConnectionRequest(t,e.origin,"rejecting a connection request, because the source was not opened by a glue API call")}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},this.defaultTargetString);this.port?.postMessage(e)}handleClientUnload(e){const t=e.data.glue42core,n=t?.data.clientId;if(!n)return void this.logger.warn("cannot process grand child unload, because the provided id was not valid");this.children.find((e=>e.grandChildId===n))?(this.logger.debug(`handling grandchild unload for id: ${n}`),this.children=this.children.filter((e=>e.grandChildId!==n))):this.logger.warn("cannot process grand child unload, because this client is unaware of this grandchild")}handlePlatformPing(){}notifyStatusChanged(e,t){this.iAmConnected=e,this.registry.execute("onConnectedChanged",e,t)}checkMessageTypeValid(e){return"string"==typeof e&&!!this.messages[e]}rejectConnectionRequest(e,t,n){this.rejected=!0,this.logger.error(n);const s={glue42core:{type:this.messages.connectionRejected.name}};e.postMessage(s,t)}requestConnectionPermissionFromExt(){return this.waitForContentScript().then((()=>N(((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"}},this.defaultTargetString)}),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():N((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),s=new Set([...t,...n]);if(!s.size&&!this.extContentAvailable)throw new Error(e);if(!s.size&&this.extContentAvailable)return void await this.requestConnectionPermissionFromExt();if((await this.isParentCheckSuccess(this.confirmParent(Array.from(s)))).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=N((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-${O(10)}`,this.selfAssignedWindowId):void 0}}class D{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 $(e,t,n,s,i){null==e&&(e="global"),s=s??["success"],i=i??["error"];let r,o="global"===e,a=!1,c=!1;const d=x();t.disconnected((function(){c=!1,n.debug("connection is down"),o=!1,a=!0,d.execute("onLeft",{disconnected:!0})})),t.loggedIn((function(){c=!0,a&&(n.debug("connection is now up - trying to reconnect..."),u(r))})),t.on("success",(e=>g(e))),t.on("error",(e=>p(e))),t.on("result",(e=>g(e))),s&&s.forEach((e=>{t.on(e,(e=>g(e)))})),i&&i.forEach((e=>{t.on(e,(e=>p(e)))}));const h={};function u(t){return r=t,new Promise(((s,i)=>{if(o)return void s({});let r;if("global"===e)r=c?Promise.resolve({}):Promise.reject("not connected to gateway");else{n.debug(`joining domain ${e}`);r=b({type:"join",destination:e,domain:"global",options:t})}r.then((()=>{!function(){n.debug("did join "+e),o=!0;const t=a;a=!1,d.execute("onJoined",t)}(),s({})})).catch((t=>{n.debug("error joining "+e+" domain: "+JSON.stringify(t)),i(t)}))}))}function l(e){return o&&e(!1),d.add("onJoined",e)}function p(t){if(e!==t.domain)return;const n=t.request_id;if(!n)return;const s=h[n];s&&s.error(t)}function g(t){if(t.domain!==e)return;const n=t.request_id;if(!n)return;const s=h[n];s&&s.success(t)}function m(){return O(10)}let f=[];function b(s,i,r){if(s.type&&-1===["hello","join"].indexOf(s.type)&&!o){console.warn(`trying to send a message (${s.domain} ${s.type}) but not connected, will queue`);const e=new M;if(f.push({msg:s,tag:i,options:r,pw:e}),1===f.length){const e=l((()=>{n.info(`joined - will now send queued messages (${f.length} -> [${f.map((e=>e.msg.type))}])`),f.forEach((e=>{b(e.msg,e.tag,e.options).then((t=>e.pw.resolve(t))).catch((t=>e.pw.reject(t)))})),f=[],e()}))}return e.promise}r=r??{},s.request_id=s.request_id??m(),s.domain=s.domain??e,r.skipPeerId||(s.peer_id=t.peerId);const a=s.request_id;return new Promise(((e,o)=>{h[a]={success:t=>{delete h[a],t._tag=i,e(t)},error:e=>{n.warn(`Gateway error - ${JSON.stringify(e)}`),delete h[a],e._tag=i,o(e)}},t.send(s,r).catch((e=>{h[a].error({err:e})}))}))}return{join:u,leave:function(){return"global"===e?Promise.resolve():(n.debug("stopping session "+e+"..."),a=!1,b({type:"leave",destination:e,domain:"global"}).then((()=>{o=!1,d.execute("onLeft")})).catch((()=>{o=!1,d.execute("onLeft")})))},onJoined:l,onLeft:function(e){return o||e(),d.add("onLeft",e)},send:b,sendFireAndForget:function(n){return n.request_id=n.request_id?n.request_id:m(),n.domain=n.domain??e,n.peer_id=t.peerId,t.send(n)},on:(s,i)=>{t.on(s,(t=>{if(t.domain===e)try{i(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 q{settings;logger;protocolVersion=3;peerId;token;info;resolvedIdentity;availableDomains;gatewayToken;replayer;messageHandlers={};ids=1;registry=x();_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 D;_isLoggedIn=!1;shouldTryLogin=!0;pingTimer;sessions=[];globalDomain;initialLogin=!0;initialLoginAttempts=3;loginConfig;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 C(e.inproc,t.subLogger("inMemory"));else if(e.sharedWorker)this.transport=new T(e.sharedWorker,t.subLogger("shared-worker"));else if(e.webPlatform)this.transport=new L(e.webPlatform,t.subLogger("web-platform"),e.identity);else{if(void 0===e.ws)throw new Error("No connection information specified");this.transport=new R(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)),s=this.transport.onMessage(this.handleTransportMessage.bind(this));this._transportSubscriptions.push(n),this._transportSubscriptions.push(s),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._defaultAuth||(this._defaultAuth=e),this._swapTransport){this.logger.trace("Detected a transport swap, swapping transports");e=this.transportSwap()??e}this.logger.trace(`Starting login for transport: ${this.transport.name()} and auth ${JSON.stringify(e)}`);try{await this.transport.open(),this.logger.trace(`Transport: ${this.transport.name()} opened, logging in`),P("connection").mark("transport-opened");const n=await this.loginCore(e,t);return this.logger.trace(`Logged in with identity: ${JSON.stringify(n)}`),P("connection").mark("protocol-logged-in"),n}catch(e){throw this._switchInProgress&&(this.logger.trace("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 s=this.sessions.find((t=>t.domain===e));return s||(s=$(e,this,this.logger.subLogger(`domain=${e}`),t,n),this.sessions.push(s)),s}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.registry.execute("onLoggedIn")}distributeMessage(e,t){const n=this.messageHandlers[t.toLowerCase()];void 0!==n&&Object.keys(n).forEach((t=>{const s=n[t];if(void 0!==s)try{s(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._connected=e,e?(this.settings?.replaySpecs?.length&&(this.replayer=new E(this.settings.replaySpecs),this.replayer.init(this)),this.registry.execute("connected")):(this.handleDisconnected(),this.registry.execute("disconnected")))}handleDisconnected(){this.setLoggedIn(!1);if(this.shouldTryLogin&&this.initialLogin){if(this.initialLoginAttempts<=0)return;this.initialLoginAttempts--}if(this.logger.debug("disconnected - will try new login?"+this.shouldTryLogin),this.shouldTryLogin){if(!this.loginConfig)throw new Error("no login info");this.login(this.loginConfig,!0).catch((()=>{setTimeout(this.handleDisconnected.bind(this),this.settings.reconnectInterval||1e3)}))}}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 N((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 R(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.logger.info("logging in..."),this.loginConfig=e,this.loginConfig||(this.loginConfig={username:"",password:""}),this.shouldTryLogin=!0;const n=await this.setupAuthConfig(e,t),s={type:"hello",identity:this.settings.identity,authentication:n};e.sessionId&&(s.request_id=e.sessionId),this.globalDomain=$("global",this,this.logger.subLogger("global-domain"),["welcome","token","authentication-request"]);const i={skipPeerId:!0};this.initialLogin&&(i.retryInterval=this.settings.reconnectInterval,i.maxRetries=this.settings.reconnectAttempts);try{const t=await this.tryAuthenticate(this.globalDomain,s,i,e);return this.initialLogin=!1,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,s){let i;for(;;){const r=await e.send(t,void 0,n);if("authentication-request"!==r.type){if("welcome"===r.type){i=r;break}throw"error"===r.type?new Error("Authentication failed: "+r.reason):new Error("Unexpected message type during authentication: "+r.type)}{const e=Buffer.from(r.authentication.token,"base64");s.flowCallback&&s.sessionId&&(t.authentication.token=(await s.flowCallback(s.sessionId,e)).data.toString("base64")),t.request_id=s.sessionId}}return i}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 F=["trace","debug","info","warn","error","off"];class U{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(e){const t=this.subLoggers.filter((t=>t.name===e))[0];if(void 0!==t)return t;Object.keys(this).forEach((t=>{if(t===e)throw new Error("This sub logger name is not allowed.")}));const n=new U(e,this,this.customLogFn?this.logFn:void 0);return this.subLoggers.push(n),n}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 F.indexOf(e)>=F.indexOf(t||this.consoleLevel()||"trace")}publishMessage(e,t,n){const s=this.loggerFullName;if("error"===e&&!n){const e=new Error;e.stack&&(t=t+"\n"+e.stack.split("\n").slice(4).join("\n"))}if(this.canPublish(e,this.publishLevel())){const i=U.Interop;if(i)try{if(i.methods({name:U.InteropMethodName}).length>0){const r={msg:t,logger:s,level:e};n&&n instanceof Error&&(r.error={message:n.message,stack:n.stack??""}),i.invoke(U.InteropMethodName,r)}}catch{}}if(this.canPublish(e)){let i="";if(this.includeTimeAndLevel){const t=new Date;i=`[${`${t.getHours()}:${t.getMinutes()}:${t.getSeconds()}:${t.getMilliseconds()}`}] [${e}] `}const r=`${i}${s}: ${t}`;switch(e){case"trace":this.logFn.debug(r);break;case"debug":this.logFn.debug?this.logFn.debug(r):this.logFn.log(r);break;case"info":this.logFn.info(r);break;case"warn":this.logFn.warn(r);break;case"error":this.logFn.error(r,n)}}}}const B="create-context",W="created",J="destroyed",K="context-created",H="context-added",V="subscribe-context",G="subscribed-context",z="unsubscribe-context",Q="destroy-context",X="context-destroyed",Y="update-context",Z="context-updated",ee="joined",te={get name(){return"context"},get types(){return[B,W,J,K,H,V,G,z,Q,X,Y,Z,ee]}};var ne="6.5.2";class se{name;contextId;context;isAnnounced;joinedActivity;updateCallbacks={};activityId;sentExplicitSubscription;hasReceivedSnapshot;constructor(e,t,n,s){this.contextId=e,this.name=t,this.isAnnounced=n,this.activityId=s,this.context={}}hasCallbacks(){return Object.keys(this.updateCall