@ikonai/sdk 1.5.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ function e(e){return e}function t(e){if(e.length<8)throw Error(`Protocol message too short`);return(e[4]|e[5]<<8|e[6]<<16|e[7]<<24)>>>0}function n(e){return t(e)&4294901760}function r(e){let t=ee(e),n=new DataView(t.buffer,t.byteOffset,t.byteLength);if(t.length<27)throw Error(`Protocol payload too short`);let r=n.getUint32(0,!0),i=n.getUint32(4,!0),a=n.getUint32(8,!0),o=n.getUint32(12,!0),s=n.getUint32(16,!0),c=n.getUint32(20,!0),l=n.getUint8(24),u=n.getUint8(25),d=n.getUint8(26);if(27+c*4>t.length)throw Error(`Protocol header exceeds payload length`);let f=[],p=27;for(let e=0;e<c;e++)f.push(n.getUint32(p,!0)),p+=4;return{length:r,opcode:i,senderId:a,trackId:o,sequenceId:s,targetIds:f,payloadVersion:l,payloadType:u,flags:d}}function i(t,n,r,i,a){let o=a?.trackId??0,s=a?.sequenceId??0,c=a?.flags??0,l=a?.targetIds??[],u=a?.payloadType??8,d=27+l.length*4,f=d+n.length,p=new Uint8Array(f),m=new DataView(p.buffer);m.setUint32(0,f,!0),m.setUint32(4,t>>>0,!0),m.setUint32(8,i>>>0,!0),m.setUint32(12,o>>>0,!0),m.setUint32(16,s>>>0,!0),m.setUint32(20,l.length>>>0,!0),m.setUint8(24,r&255),m.setUint8(25,u&255),m.setUint8(26,c&255);let h=27;for(let e=0;e<l.length;e++)m.setUint32(h,l[e]>>>0,!0),h+=4;return p.set(n,d),e(p)}let a=function(e){return e[e.Null=1]=`Null`,e[e.Bool=2]=`Bool`,e[e.Int32=3]=`Int32`,e[e.Int64=4]=`Int64`,e[e.UInt32=5]=`UInt32`,e[e.UInt64=6]=`UInt64`,e[e.Float32=7]=`Float32`,e[e.Float64=8]=`Float64`,e[e.Array=9]=`Array`,e[e.Dict=10]=`Dict`,e[e.Object=11]=`Object`,e[e.String=12]=`String`,e[e.Binary=13]=`Binary`,e[e.Guid=14]=`Guid`,e}({});const o=new TextEncoder;new TextDecoder(`utf-8`,{fatal:!0});var s=class e{buffer=new f;cached;constructor(e=1){this.buffer.writeByte(161),this.buffer.writeVarUInt(e>>>0)}writeInt32Field(e,t){this.writeFixedField(e,3,()=>this.buffer.writeInt32(t|0))}writeUInt32Field(e,t){this.writeFixedField(e,5,()=>this.buffer.writeUInt32(t>>>0))}writeInt64Field(e,t){this.writeFixedField(e,4,()=>this.buffer.writeBigInt64(t))}writeUInt64Field(e,t){this.writeFixedField(e,6,()=>this.buffer.writeBigUInt64(t))}writeFloat32Field(e,t){this.writeFixedField(e,7,()=>this.buffer.writeFloat32(t))}writeFloat64Field(e,t){this.writeFixedField(e,8,()=>this.buffer.writeFloat64(t))}writeBoolField(e,t){this.writeFixedField(e,2,()=>this.buffer.writeByte(+!!t))}writeGuidField(e,t){let n=t instanceof d?t.asBytes():t;if(n.length!==16)throw Error(`Guid payload must be 16 bytes`);this.writeFixedField(e,14,()=>this.buffer.writeBytes(n))}writeStringField(e,t){let n=o.encode(t??``);this.writeVariableField(e,12,n)}writeBinaryField(e,t){this.writeVariableField(e,13,t)}writeObjectField(t,n,r){let i=new e(n);r(i);let a=i.finish();this.writeVariableField(t,11,a)}writeArrayField(e,t,n){let r=new c(t);n(r);let i=r.finish();this.writeVariableField(e,9,i)}writeDictionaryField(e,t,n,r){let i=new l(t,n);r(i);let a=i.finish();this.writeVariableField(e,10,a)}finish(){return this.cached||=(this.buffer.writeByte(162),this.buffer.toUint8Array()),this.cached}writeFixedField(e,t,n){this.writeFieldHeader(e,t,0),n()}writeVariableField(e,t,n){this.writeFieldHeader(e,t,n.length),this.buffer.writeBytes(n)}writeFieldHeader(e,t,n){this.buffer.writeUInt32(e>>>0),this.buffer.writeByte(p(t)),m(t)&&this.buffer.writeVarUInt(n>>>0)}},c=class e{elementType;payload=new f;count=0;constructor(e){this.elementType=e}writeInt32(e){this.ensureElementType(3),this.count++,this.payload.writeInt32(e|0)}writeUInt32(e){this.ensureElementType(5),this.count++,this.payload.writeUInt32(e>>>0)}writeInt64(e){this.ensureElementType(4),this.count++,this.payload.writeBigInt64(e)}writeUInt64(e){this.ensureElementType(6),this.count++,this.payload.writeBigUInt64(e)}writeFloat32(e){this.ensureElementType(7),this.count++,this.payload.writeFloat32(e)}writeFloat64(e){this.ensureElementType(8),this.count++,this.payload.writeFloat64(e)}writeBool(e){this.ensureElementType(2),this.count++,this.payload.writeByte(+!!e)}writeGuid(e){this.ensureElementType(14),this.count++;let t=e instanceof d?e.asBytes():e;if(t.length!==16)throw Error(`Guid payload must be 16 bytes`);this.payload.writeBytes(t)}writeString(e){this.ensureElementType(12),this.count++;let t=o.encode(e??``);this.payload.writeVarUInt(t.length),this.payload.writeBytes(t)}writeBinary(e){this.ensureElementType(13),this.count++,this.payload.writeVarUInt(e.length),this.payload.writeBytes(e)}writeObject(e,t){this.ensureElementType(11),this.count++;let n=new s(e);t(n);let r=n.finish();this.payload.writeVarUInt(r.length),this.payload.writeBytes(r)}writeArray(t,n){this.ensureElementType(9),this.count++;let r=new e(t);n(r);let i=r.finish();this.payload.writeBytes(i)}writeDictionary(e,t,n){this.ensureElementType(10),this.count++;let r=new l(e,t);n(r);let i=r.finish();this.payload.writeBytes(i)}finish(){let e=new f;return e.writeByte(p(this.elementType)),e.writeVarUInt(this.count),e.writeBytes(this.payload.toUint8Array()),e.toUint8Array()}ensureElementType(e){if(this.elementType!==e)throw Error(`Array element type is ${a[this.elementType]}, expected ${a[e]}`)}},l=class{keyType;valueType;payload=new f;count=0;entryOpen=!1;constructor(e,t){this.keyType=e,this.valueType=t,h(e)}beginEntry(){if(this.entryOpen)throw Error(`Previous dictionary entry not completed`);return this.count++,this.entryOpen=!0,new u(this.keyType,this.valueType,this.payload,()=>{this.entryOpen=!1})}finish(){if(this.entryOpen)throw Error(`Dictionary entry not completed`);let e=new f;return e.writeByte(p(this.keyType)),e.writeByte(p(this.valueType)),e.writeVarUInt(this.count),e.writeBytes(this.payload.toUint8Array()),e.toUint8Array()}},u=class{keyType;valueType;payload;onComplete;keyWritten=!1;valueWritten=!1;completed=!1;constructor(e,t,n,r){this.keyType=e,this.valueType=t,this.payload=n,this.onComplete=r}writeKeyInt32(e){this.ensureKeyType(3),this.payload.writeInt32(e|0),this.keyWritten=!0}writeKeyUInt32(e){this.ensureKeyType(5),this.payload.writeUInt32(e>>>0),this.keyWritten=!0}writeKeyInt64(e){this.ensureKeyType(4),this.payload.writeBigInt64(e),this.keyWritten=!0}writeKeyUInt64(e){this.ensureKeyType(6),this.payload.writeBigUInt64(e),this.keyWritten=!0}writeKeyFloat32(e){this.ensureKeyType(7),this.payload.writeFloat32(e),this.keyWritten=!0}writeKeyFloat64(e){this.ensureKeyType(8),this.payload.writeFloat64(e),this.keyWritten=!0}writeKeyBool(e){this.ensureKeyType(2),this.payload.writeByte(+!!e),this.keyWritten=!0}writeKeyGuid(e){this.ensureKeyType(14);let t=e instanceof d?e.asBytes():e;if(t.length!==16)throw Error(`Guid payload must be 16 bytes`);this.payload.writeBytes(t),this.keyWritten=!0}writeKeyString(e){this.ensureKeyType(12);let t=o.encode(e??``);this.payload.writeVarUInt(t.length),this.payload.writeBytes(t),this.keyWritten=!0}writeKeyBinary(e){this.ensureKeyType(13),this.payload.writeVarUInt(e.length),this.payload.writeBytes(e),this.keyWritten=!0}writeValueInt32(e){this.ensureValueType(3),this.payload.writeInt32(e|0),this.valueWritten=!0}writeValueUInt32(e){this.ensureValueType(5),this.payload.writeUInt32(e>>>0),this.valueWritten=!0}writeValueInt64(e){this.ensureValueType(4),this.payload.writeBigInt64(e),this.valueWritten=!0}writeValueUInt64(e){this.ensureValueType(6),this.payload.writeBigUInt64(e),this.valueWritten=!0}writeValueFloat32(e){this.ensureValueType(7),this.payload.writeFloat32(e),this.valueWritten=!0}writeValueFloat64(e){this.ensureValueType(8),this.payload.writeFloat64(e),this.valueWritten=!0}writeValueBool(e){this.ensureValueType(2),this.payload.writeByte(+!!e),this.valueWritten=!0}writeValueGuid(e){this.ensureValueType(14);let t=e instanceof d?e.asBytes():e;if(t.length!==16)throw Error(`Guid payload must be 16 bytes`);this.payload.writeBytes(t),this.valueWritten=!0}writeNullValue(){this.ensureValueType(1),this.valueWritten=!0}writeValueBinary(e){this.ensureValueType(13),this.payload.writeVarUInt(e.length),this.payload.writeBytes(e),this.valueWritten=!0}writeValueString(e){this.ensureValueType(12);let t=o.encode(e??``);this.payload.writeVarUInt(t.length),this.payload.writeBytes(t),this.valueWritten=!0}writeValueObject(e,t){this.ensureValueType(11);let n=new s(e);t(n);let r=n.finish();this.payload.writeVarUInt(r.length),this.payload.writeBytes(r),this.valueWritten=!0}writeValueArray(e,t){this.ensureValueType(9);let n=new c(e);t(n);let r=n.finish();this.payload.writeBytes(r),this.valueWritten=!0}writeValueDictionary(e,t,n){this.ensureValueType(10);let r=new l(e,t);n(r);let i=r.finish();this.payload.writeBytes(i),this.valueWritten=!0}complete(){if(!this.completed){if(!this.keyWritten||!this.valueWritten)throw Error(`Dictionary entry must write both key and value`);this.completed=!0,this.onComplete()}}ensureKeyType(e){if(this.keyType!==e)throw Error(`Dictionary key type is ${a[this.keyType]}, expected ${a[e]}`)}ensureValueType(e){if(this.valueType!==e)throw Error(`Dictionary value type is ${a[this.valueType]}, expected ${a[e]}`)}},d=class e{bytes;constructor(e){this.bytes=e}static fromString(t){if(!t)throw Error(`Guid string is empty`);let n=t.replace(/-/g,``);if(n.length!==32)throw Error(`Guid string must be 32 hex characters`);let r=new Uint8Array(16),i=e.parseHexSlice(n,0,8),a=e.parseHexSlice(n,8,4),o=e.parseHexSlice(n,12,4);e.writeUInt32LE(r,0,i),e.writeUInt16LE(r,4,a),e.writeUInt16LE(r,6,o);for(let t=0;t<8;t++)r[8+t]=e.parseHexSlice(n,16+t*2,2);return new e(r)}static fromBytes(t){if(t.length!==16)throw Error(`Guid byte array must be 16 bytes`);return new e(Uint8Array.from(t))}static createZero(){return new e(new Uint8Array(16))}static createRandom(){let t=new Uint8Array(16),n=globalThis.crypto;if(n?.getRandomValues)n.getRandomValues(t);else for(let e=0;e<t.length;e++)t[e]=Math.floor(Math.random()*256);return t[6]=t[6]&15|64,t[8]=t[8]&63|128,new e(t)}toString(){let t=this.bytes;return[e.toHex(e.readUInt32LE(t,0),8),e.toHex(e.readUInt16LE(t,4),4),e.toHex(e.readUInt16LE(t,6),4),g(t.subarray(8,10)),g(t.subarray(10,16))].join(`-`)}asBytes(){return this.bytes.slice()}static parseHexSlice(e,t,n){let r=e.substr(t,n),i=Number.parseInt(r,16);if(Number.isNaN(i))throw Error(`Guid string contains invalid characters`);return i>>>0}static writeUInt32LE(e,t,n){let r=n>>>0;e[t]=r&255,e[t+1]=r>>>8&255,e[t+2]=r>>>16&255,e[t+3]=r>>>24&255}static writeUInt16LE(e,t,n){let r=n&65535;e[t]=r&255,e[t+1]=r>>>8&255}static readUInt32LE(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0}static readUInt16LE(e,t){return(e[t]|e[t+1]<<8)&65535}static toHex(e,t){return(e>>>0).toString(16).padStart(t,`0`)}},f=class e{static INITIAL_CAPACITY=256;buffer;dataView;length=0;constructor(){this.buffer=new Uint8Array(e.INITIAL_CAPACITY),this.dataView=new DataView(this.buffer.buffer)}ensureCapacity(e){let t=this.length+e;if(t<=this.buffer.length)return;let n=this.buffer.length;for(;n<t;)n*=2;let r=new Uint8Array(n);r.set(this.buffer.subarray(0,this.length)),this.buffer=r,this.dataView=new DataView(this.buffer.buffer)}writeByte(e){this.ensureCapacity(1),this.buffer[this.length++]=e&255}writeBytes(e){this.ensureCapacity(e.length),this.buffer.set(e,this.length),this.length+=e.length}writeUInt32(e){this.ensureCapacity(4),this.dataView.setUint32(this.length,e>>>0,!0),this.length+=4}writeInt32(e){this.ensureCapacity(4),this.dataView.setInt32(this.length,e|0,!0),this.length+=4}writeFloat32(e){this.ensureCapacity(4),this.dataView.setFloat32(this.length,e,!0),this.length+=4}writeFloat64(e){this.ensureCapacity(8),this.dataView.setFloat64(this.length,e,!0),this.length+=8}writeBigInt64(e){this.ensureCapacity(8),this.dataView.setBigInt64(this.length,e,!0),this.length+=8}writeBigUInt64(e){this.ensureCapacity(8),this.dataView.setBigUint64(this.length,e,!0),this.length+=8}writeVarUInt(e){let t=e>>>0;for(;t>=128;)this.ensureCapacity(1),this.buffer[this.length++]=t&127|128,t>>>=7;this.ensureCapacity(1),this.buffer[this.length++]=t&127}toUint8Array(){return this.buffer.slice(0,this.length)}};function p(e,t=0){if(t&240)throw Error(`Teleport flags must fit into 4 bits`);return(e&15)<<4|t&15}function m(e){return e===12||e===13||e===9||e===11||e===10}function h(e){if(e===9||e===11||e===10||e===1)throw Error(`Dictionary keys must be primitive Teleport types`)}function g(e){return Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``)}function ee(e){return e instanceof Uint8Array?e:new Uint8Array(e)}let _=function(e){return e[e.None=0]=`None`,e[e.WebSocket=1]=`WebSocket`,e[e.WebSocketProxy=2]=`WebSocketProxy`,e[e.WebTransport=4]=`WebTransport`,e[e.WebTransportProxy=8]=`WebTransportProxy`,e[e.Tcp=16]=`Tcp`,e[e.TcpProxy=32]=`TcpProxy`,e[e.Https=64]=`Https`,e[e.WebRTC=128]=`WebRTC`,e[e.TcpTls=256]=`TcpTls`,e[e.Udp=512]=`Udp`,e[e.UdpDtls=1024]=`UdpDtls`,e[e.HttpStream=2048]=`HttpStream`,e[e.HttpStreamProxy=4096]=`HttpStreamProxy`,e}({}),v=function(e){return e[e.NONE=0]=`NONE`,e[e.CONSTANT_GROUP_BITS=15]=`CONSTANT_GROUP_BITS`,e[e.CONSTANT_GROUP_OFFSET=16]=`CONSTANT_GROUP_OFFSET`,e[e.GROUP_CORE=65536]=`GROUP_CORE`,e[e.CORE_AUTH_RESPONSE=65537]=`CORE_AUTH_RESPONSE`,e[e.CORE_AUTH_TICKET=65538]=`CORE_AUTH_TICKET`,e[e.CORE_GLOBAL_STATE=65539]=`CORE_GLOBAL_STATE`,e[e.CORE_ON_SERVER_STATUS_PING=65540]=`CORE_ON_SERVER_STATUS_PING`,e[e.CORE_ON_USER_JOINED=65541]=`CORE_ON_USER_JOINED`,e[e.CORE_ON_USER_LEFT=65542]=`CORE_ON_USER_LEFT`,e[e.CORE_ON_CLIENT_JOINED=65543]=`CORE_ON_CLIENT_JOINED`,e[e.CORE_ON_CLIENT_LEFT=65544]=`CORE_ON_CLIENT_LEFT`,e[e.CORE_ON_SERVER_STARTED=65545]=`CORE_ON_SERVER_STARTED`,e[e.CORE_ON_SERVER_STOPPED=65546]=`CORE_ON_SERVER_STOPPED`,e[e.CORE_ON_SERVER_STOPPING=65547]=`CORE_ON_SERVER_STOPPING`,e[e.CORE_ON_CLIENT_READY=65548]=`CORE_ON_CLIENT_READY`,e[e.CORE_CLIENT_READY=65549]=`CORE_CLIENT_READY`,e[e.CORE_SERVER_INIT=65550]=`CORE_SERVER_INIT`,e[e.CORE_ON_PLUGIN_RELOADED=65551]=`CORE_ON_PLUGIN_RELOADED`,e[e.CORE_DYNAMIC_CONFIG=65555]=`CORE_DYNAMIC_CONFIG`,e[e.CORE_PROXY_RPC_AUTH_TICKET=65556]=`CORE_PROXY_RPC_AUTH_TICKET`,e[e.CORE_UPDATE_CLIENT_CONTEXT=65558]=`CORE_UPDATE_CLIENT_CONTEXT`,e[e.CORE_BACKGROUND_WORK_ACTIVE=65559]=`CORE_BACKGROUND_WORK_ACTIVE`,e[e.CORE_RESET_IDLE=65560]=`CORE_RESET_IDLE`,e[e.CORE_CLIENT_DISCONNECTING=65561]=`CORE_CLIENT_DISCONNECTING`,e[e.CORE_ON_APP_READY=65562]=`CORE_ON_APP_READY`,e[e.CORE_ON_FRONTEND_RELOADED=65563]=`CORE_ON_FRONTEND_RELOADED`,e[e.CORE_ON_USER_DATA_ERASED=65564]=`CORE_ON_USER_DATA_ERASED`,e[e.CORE_WEBRTC_OFFER=65566]=`CORE_WEBRTC_OFFER`,e[e.CORE_WEBRTC_ANSWER=65567]=`CORE_WEBRTC_ANSWER`,e[e.CORE_WEBRTC_ICE_CANDIDATE=65568]=`CORE_WEBRTC_ICE_CANDIDATE`,e[e.CORE_WEBRTC_READY=65569]=`CORE_WEBRTC_READY`,e[e.CORE_WEBRTC_AUDIO_SEGMENT=65570]=`CORE_WEBRTC_AUDIO_SEGMENT`,e[e.CORE_WEBRTC_TRACK_MAP=65571]=`CORE_WEBRTC_TRACK_MAP`,e[e.CORE_WEBRTC_VIDEO_CAPTURE=65572]=`CORE_WEBRTC_VIDEO_CAPTURE`,e[e.CORE_WEBRTC_ICE_SERVERS_REQUEST=65573]=`CORE_WEBRTC_ICE_SERVERS_REQUEST`,e[e.CORE_WEBRTC_ICE_SERVERS_RESPONSE=65574]=`CORE_WEBRTC_ICE_SERVERS_RESPONSE`,e[e.CORE_WEBRTC_CLOSE=65575]=`CORE_WEBRTC_CLOSE`,e[e.CORE_RELAY_AGENT_AUTH=65576]=`CORE_RELAY_AGENT_AUTH`,e[e.CORE_RELAY_AGENT_AUTH_RESULT=65577]=`CORE_RELAY_AGENT_AUTH_RESULT`,e[e.CORE_RELAY_HEARTBEAT=65578]=`CORE_RELAY_HEARTBEAT`,e[e.CORE_RELAY_TCP_CONNECTION_OPENED=65579]=`CORE_RELAY_TCP_CONNECTION_OPENED`,e[e.CORE_RELAY_TCP_CONNECTION_CLOSED=65580]=`CORE_RELAY_TCP_CONNECTION_CLOSED`,e[e.CORE_RELAY_TCP_DATA=65581]=`CORE_RELAY_TCP_DATA`,e[e.CORE_RELAY_UDP_DATA=65582]=`CORE_RELAY_UDP_DATA`,e[e.CORE_RELAY_ADD_TUNNEL=65583]=`CORE_RELAY_ADD_TUNNEL`,e[e.CORE_RELAY_TUNNEL_ADDED=65584]=`CORE_RELAY_TUNNEL_ADDED`,e[e.CORE_RELAY_REMOVE_TUNNEL=65585]=`CORE_RELAY_REMOVE_TUNNEL`,e[e.CORE_IKON_SERVER_ENDPOINT_HOST_INFO=65586]=`CORE_IKON_SERVER_ENDPOINT_HOST_INFO`,e[e.CORE_CLIENT_INITIALIZATION=65587]=`CORE_CLIENT_INITIALIZATION`,e[e.CORE_CLIENT_LIFECYCLE_BATCH=65588]=`CORE_CLIENT_LIFECYCLE_BATCH`,e[e.CORE_APP_CONFIG=65589]=`CORE_APP_CONFIG`,e[e.GROUP_KEEPALIVE=131072]=`GROUP_KEEPALIVE`,e[e.KEEPALIVE_REQUEST=131073]=`KEEPALIVE_REQUEST`,e[e.KEEPALIVE_RESPONSE=131074]=`KEEPALIVE_RESPONSE`,e[e.GROUP_EVENTS=262144]=`GROUP_EVENTS`,e[e.EVENTS_PROFILE_UPDATE=262145]=`EVENTS_PROFILE_UPDATE`,e[e.EVENTS_SPEECH_PLAYBACK_COMPLETE=262147]=`EVENTS_SPEECH_PLAYBACK_COMPLETE`,e[e.GROUP_ANALYTICS=524288]=`GROUP_ANALYTICS`,e[e.ANALYTICS_LOGS=524289]=`ANALYTICS_LOGS`,e[e.ANALYTICS_EVENTS=524290]=`ANALYTICS_EVENTS`,e[e.ANALYTICS_USAGES=524291]=`ANALYTICS_USAGES`,e[e.ANALYTICS_USAGE=524292]=`ANALYTICS_USAGE`,e[e.ANALYTICS_SPECIAL_LOG=524293]=`ANALYTICS_SPECIAL_LOG`,e[e.ANALYTICS_PROCESSING_UPDATE=524294]=`ANALYTICS_PROCESSING_UPDATE`,e[e.ANALYTICS_REACTIVE_PROCESSING_UPDATE=524295]=`ANALYTICS_REACTIVE_PROCESSING_UPDATE`,e[e.ANALYTICS_IKON_PROXY_SERVER_STATS=524296]=`ANALYTICS_IKON_PROXY_SERVER_STATS`,e[e.ANALYTICS_IKON_RELAY_SERVER_STATS=524297]=`ANALYTICS_IKON_RELAY_SERVER_STATS`,e[e.ANALYTICS_IKON_TURN_SERVER_STATS=524298]=`ANALYTICS_IKON_TURN_SERVER_STATS`,e[e.ANALYTICS_IKON_HOST_SERVER_STATS=524299]=`ANALYTICS_IKON_HOST_SERVER_STATS`,e[e.ANALYTICS_TRAFFIC_USAGE=524300]=`ANALYTICS_TRAFFIC_USAGE`,e[e.GROUP_ACTIONS=1048576]=`GROUP_ACTIONS`,e[e.ACTION_CALL=1048577]=`ACTION_CALL`,e[e.ACTION_ACTIVE=1048578]=`ACTION_ACTIVE`,e[e.ACTION_TEXT_OUTPUT=1048579]=`ACTION_TEXT_OUTPUT`,e[e.ACTION_TEXT_OUTPUT_DELTA=1048580]=`ACTION_TEXT_OUTPUT_DELTA`,e[e.ACTION_TEXT_OUTPUT_DELTA_FULL=1048581]=`ACTION_TEXT_OUTPUT_DELTA_FULL`,e[e.ACTION_SET_STATE=1048582]=`ACTION_SET_STATE`,e[e.ACTION_TAP=1048583]=`ACTION_TAP`,e[e.ACTION_PAN=1048584]=`ACTION_PAN`,e[e.ACTION_ZOOM=1048585]=`ACTION_ZOOM`,e[e.ACTION_OPEN_EXTERNAL_URL=1048592]=`ACTION_OPEN_EXTERNAL_URL`,e[e.ACTION_FUNCTION_REGISTER=1048600]=`ACTION_FUNCTION_REGISTER`,e[e.ACTION_FUNCTION_CALL=1048601]=`ACTION_FUNCTION_CALL`,e[e.ACTION_FUNCTION_RESULT=1048602]=`ACTION_FUNCTION_RESULT`,e[e.ACTION_GENERATE_ANSWER=1048603]=`ACTION_GENERATE_ANSWER`,e[e.ACTION_REGENERATE_ANSWER=1048604]=`ACTION_REGENERATE_ANSWER`,e[e.ACTION_CLEAR_STATE=1048606]=`ACTION_CLEAR_STATE`,e[e.ACTION_CLASSIFICATION_RESULT=1048609]=`ACTION_CLASSIFICATION_RESULT`,e[e.ACTION_AUDIO_STOP=1048610]=`ACTION_AUDIO_STOP`,e[e.ACTION_CALL_TEXT=1048611]=`ACTION_CALL_TEXT`,e[e.ACTION_CANCEL_GENERATION=1048613]=`ACTION_CANCEL_GENERATION`,e[e.ACTION_SPEECH_RECOGNIZED=1048615]=`ACTION_SPEECH_RECOGNIZED`,e[e.ACTION_CALL_RESULT=1048616]=`ACTION_CALL_RESULT`,e[e.ACTION_DOWNLOAD=1048618]=`ACTION_DOWNLOAD`,e[e.ACTION_PLAY_SOUND=1048621]=`ACTION_PLAY_SOUND`,e[e.ACTION_STOP_SOUND=1048623]=`ACTION_STOP_SOUND`,e[e.ACTION_START_RECORDING=1048624]=`ACTION_START_RECORDING`,e[e.ACTION_STOP_RECORDING=1048625]=`ACTION_STOP_RECORDING`,e[e.ACTION_FUNCTION_ENUMERATION_ITEM=1048627]=`ACTION_FUNCTION_ENUMERATION_ITEM`,e[e.ACTION_FUNCTION_ENUMERATION_END=1048628]=`ACTION_FUNCTION_ENUMERATION_END`,e[e.ACTION_FUNCTION_CANCEL=1048629]=`ACTION_FUNCTION_CANCEL`,e[e.ACTION_FUNCTION_DISPOSE=1048630]=`ACTION_FUNCTION_DISPOSE`,e[e.ACTION_FUNCTION_ERROR=1048631]=`ACTION_FUNCTION_ERROR`,e[e.ACTION_FUNCTION_ACK=1048632]=`ACTION_FUNCTION_ACK`,e[e.ACTION_FUNCTION_AWAITING_APPROVAL=1048633]=`ACTION_FUNCTION_AWAITING_APPROVAL`,e[e.ACTION_FUNCTION_APPROVAL_REQUIRED=1048634]=`ACTION_FUNCTION_APPROVAL_REQUIRED`,e[e.ACTION_FUNCTION_APPROVAL_RESPONSE=1048635]=`ACTION_FUNCTION_APPROVAL_RESPONSE`,e[e.UI_UPDATE_ACK=1048636]=`UI_UPDATE_ACK`,e[e.ACTION_CALL2=1048637]=`ACTION_CALL2`,e[e.ACTION_FUNCTION_REGISTER_BATCH=1048638]=`ACTION_FUNCTION_REGISTER_BATCH`,e[e.ACTION_CUSTOM_USER_MESSAGE=1048641]=`ACTION_CUSTOM_USER_MESSAGE`,e[e.ACTION_URL_CHANGED=1048642]=`ACTION_URL_CHANGED`,e[e.ACTION_FILE_UPLOAD_PRE_START2=1048643]=`ACTION_FILE_UPLOAD_PRE_START2`,e[e.ACTION_FILE_UPLOAD_PRE_START_RESPONSE2=1048644]=`ACTION_FILE_UPLOAD_PRE_START_RESPONSE2`,e[e.ACTION_FILE_UPLOAD_START2=1048645]=`ACTION_FILE_UPLOAD_START2`,e[e.ACTION_FILE_UPLOAD_START_RESPONSE2=1048646]=`ACTION_FILE_UPLOAD_START_RESPONSE2`,e[e.ACTION_FILE_UPLOAD_DATA2=1048647]=`ACTION_FILE_UPLOAD_DATA2`,e[e.ACTION_FILE_UPLOAD_ACK2=1048648]=`ACTION_FILE_UPLOAD_ACK2`,e[e.ACTION_FILE_UPLOAD_END2=1048649]=`ACTION_FILE_UPLOAD_END2`,e[e.ACTION_FILE_UPLOAD_COMPLETE2=1048650]=`ACTION_FILE_UPLOAD_COMPLETE2`,e[e.ACTION_FUNCTION_ENUMERATION_ITEM_BATCH=1048651]=`ACTION_FUNCTION_ENUMERATION_ITEM_BATCH`,e[e.ACTION_CALL_ACK=1048652]=`ACTION_CALL_ACK`,e[e.ACTION_TRIGGER_CRON=1048653]=`ACTION_TRIGGER_CRON`,e[e.ACTION_RESULT=1048654]=`ACTION_RESULT`,e[e.UI_RESYNC_REQUEST=1048655]=`UI_RESYNC_REQUEST`,e[e.ACTION_USER_DATA_ERASURE=1048656]=`ACTION_USER_DATA_ERASURE`,e[e.ACTION_FILE_UPLOAD_RESUME2=1048657]=`ACTION_FILE_UPLOAD_RESUME2`,e[e.ACTION_FILE_UPLOAD_RESUME_RESPONSE2=1048658]=`ACTION_FILE_UPLOAD_RESUME_RESPONSE2`,e[e.GROUP_UI=2097152]=`GROUP_UI`,e[e.UI_STREAM_BEGIN=2097153]=`UI_STREAM_BEGIN`,e[e.UI_STREAM_END=2097154]=`UI_STREAM_END`,e[e.UI_STYLES=2097188]=`UI_STYLES`,e[e.UI_UPDATE=2097190]=`UI_UPDATE`,e[e.UI_STYLES_BATCH=2097192]=`UI_STYLES_BATCH`,e[e.UI_STYLES_DELETE=2097193]=`UI_STYLES_DELETE`,e[e.GROUP_COMMON=4128768]=`GROUP_COMMON`,e[e.GROUP_AUDIO=4194304]=`GROUP_AUDIO`,e[e.AUDIO_STREAM_BEGIN=4194305]=`AUDIO_STREAM_BEGIN`,e[e.AUDIO_STREAM_END=4194306]=`AUDIO_STREAM_END`,e[e.AUDIO_FRAME_VOLUME=4194308]=`AUDIO_FRAME_VOLUME`,e[e.AUDIO_FRAME=4194309]=`AUDIO_FRAME`,e[e.AUDIO_SHAPE_FRAME=4194310]=`AUDIO_SHAPE_FRAME`,e[e.AUDIO_PLAYBACK_REPORT=4194311]=`AUDIO_PLAYBACK_REPORT`,e[e.GROUP_VIDEO=8388608]=`GROUP_VIDEO`,e[e.VIDEO_STREAM_BEGIN=8388609]=`VIDEO_STREAM_BEGIN`,e[e.VIDEO_STREAM_END=8388610]=`VIDEO_STREAM_END`,e[e.VIDEO_FRAME=8388611]=`VIDEO_FRAME`,e[e.VIDEO_REQUEST_IDR_FRAME=8388612]=`VIDEO_REQUEST_IDR_FRAME`,e[e.VIDEO_INVALIDATE_FRAME=8388613]=`VIDEO_INVALIDATE_FRAME`,e[e.GROUP_ALL=16711680]=`GROUP_ALL`,e[e.GROUP_APP_LOCAL=1073741824]=`GROUP_APP_LOCAL`,e[e.CONSTANT_GROUP_MASK=2147418112]=`CONSTANT_GROUP_MASK`,e}({});function y(e){let t={};return e&&Object.assign(t,e),t}function te(e){return new s(1).finish()}function b(e,t,n){return i(131074,te(e),1,t,n)}var x=class extends Error{cause;constructor(e,t){super(e),this.cause=t,this.name=`ConnectionError`}},S=class extends x{constructor(e,t){super(e,t),this.name=`TransportError`}},C=class extends S{constructor(e){super(`No keepalive received within ${e}ms`),this.name=`KeepaliveTimeoutError`}},w=class extends S{constructor(e,t){super(e,t),this.name=`AuthRejectedError`}},T=class extends x{constructor(e){super(`Maximum reconnection attempts (${e}) exceeded`),this.name=`MaxRetriesExceededError`}},E=class extends x{pinnedTransport;pinnedTier;offeredTypes;constructor(e,t,n){let r=[e&&`?ikon-transport=${e}`,t&&`?ikon-proxy=${t}`].filter(Boolean).join(` and `);super(`No entrypoint matches ${r||`the pinned transport`}; the server offered [${n.join(`, `)}]. Change or remove the pin.`),this.pinnedTransport=e,this.pinnedTier=t,this.offeredTypes=n,this.name=`NoMatchingEndpointTypeError`}};function ne(e,t){return new Promise((n,r)=>{let i=()=>{clearTimeout(a),r(new DOMException(`Aborted`,`AbortError`))},a=setTimeout(()=>{t?.removeEventListener(`abort`,i),n()},e);if(t?.aborted){clearTimeout(a),r(new DOMException(`Aborted`,`AbortError`));return}t?.addEventListener(`abort`,i,{once:!0})})}let D=1;const re=new Map;function ie(e){D=e}const ae={0:`DEBUG`,1:`INFO`,2:`WARN`,3:`ERROR`,4:`NONE`};function oe(e,t){return`[${e}] ${t}`}function O(e,t,n,r){let i={timestamp:new Date().toISOString(),level:e,levelName:ae[e],component:t,message:n,args:r};for(let[t,n]of re)if(e>=(n?.minLevel??2))try{t(i)}catch{}if(D<=e){let i=oe(t,n);switch(e){case 0:console.debug(i,...r);break;case 1:console.info(i,...r);break;case 2:console.warn(i,...r);break;case 3:console.error(i,...r)}}}function k(e){return{debug(t,...n){O(0,e,t,n)},info(t,...n){O(1,e,t,n)},warn(t,...n){O(2,e,t,n)},error(t,...n){O(3,e,t,n)}}}function se(e){if(typeof window>`u`)return null;let t=new URLSearchParams(window.location.search),n=t.get(e);return n===null?t.get(e.replace(/-/g,`_`)):n}function ce(e){let t=se(e);return t===`true`||t!==`false`&&null}function le(){return ce(`ikon-retry`)!==!1}var A=class{buffer=new Uint8Array(65536);bufferOffset=0;bufferLength=0;dataView=null;dataViewBuffer=null;push(e,t){this.append(e);let n=this.getDataView();for(;this.bufferLength>=4;){let e=n.getUint32(this.bufferOffset,!0);if(e<4)throw this.reset(),Error(`Invalid protocol message length: ${e}`);if(this.bufferLength<e)return;let r=this.buffer.subarray(this.bufferOffset,this.bufferOffset+e);this.bufferOffset+=e,this.bufferLength-=e,t(r)}this.bufferLength===0&&(this.bufferOffset=0)}reset(){this.bufferOffset=0,this.bufferLength=0}append(e){let t=this.bufferLength+e.length,n=this.bufferOffset+this.bufferLength;if(n+e.length>this.buffer.length)if(t>this.buffer.length){let e=Math.max(t,this.buffer.length*2),r=new Uint8Array(e);r.set(this.buffer.subarray(this.bufferOffset,n)),this.buffer=r,this.bufferOffset=0,this.dataViewBuffer=null}else this.buffer.copyWithin(0,this.bufferOffset,n),this.bufferOffset=0;this.buffer.set(e,this.bufferOffset+this.bufferLength),this.bufferLength+=e.length}getDataView(){let e=this.buffer.buffer;return this.dataViewBuffer!==e&&(this.dataViewBuffer=e,this.dataView=new DataView(e)),this.dataView}};const j=k(`HttpStreamTransport`),ue=[`binary`,`sse`,`poll`];var M=class{framer=new A;callbacks;sessionId;keepaliveTimeoutMs;connectionTimeoutMs;pinnedMode;preferredMode;baseUri=``;sid=``;mode=`binary`;downstreamAbort=null;keepaliveTimeout=null;keepaliveResponseMessage=null;isClosed=!1;connected=!1;connecting=!1;sendQueue=[];sendPumpRunning=!1;firstMessageResolver=null;constructor(e){this.callbacks=e.callbacks,this.sessionId=e.sessionId,this.keepaliveTimeoutMs=e.keepaliveTimeoutMs,this.connectionTimeoutMs=e.connectionTimeoutMs??1e4,this.pinnedMode=e.httpStreamMode,this.preferredMode=e.httpStreamPreferredMode}get isConnected(){return this.connected&&!this.isClosed}get activeMode(){return this.mode}async connect(e,t){this.isClosed=!1,this.connecting=!0,this.baseUri=e;let n=Date.now(),r=null,i=this.pinnedMode?[this.pinnedMode]:de(this.preferredMode);for(let e of i){if(this.isClosed)throw new S(`HTTP stream closed while connecting`);try{this.sid=pe(),await this.openMode(t,e),this.mode=e,this.connected=!0,this.connecting=!1,this.resetKeepaliveTimeout(),j.debug(`HTTP stream connected in ${e} mode in ${Date.now()-n}ms`);return}catch(t){if(r=t instanceof Error?t:Error(String(t)),this.abortDownstream(),t instanceof w)throw this.connecting=!1,t;j.debug(`HTTP stream ${e} mode failed after ${Date.now()-n}ms: ${r.message}`)}}throw this.connecting=!1,new S(`HTTP stream failed in every mode: ${r?.message??`unknown error`}`,r??void 0)}send(e){if(this.isClosed){j.warn(`Cannot send: HTTP stream closed`);return}this.sendQueue.push(e),this.runSendPump()}close(){this.isClosed=!0,this.connected=!1,this.clearKeepaliveTimeout(),this.abortDownstream(),this.sendQueue.length=0}async openMode(e,t){let n=new AbortController;this.downstreamAbort=n;let r=Math.min(3500,this.connectionTimeoutMs),i=setTimeout(()=>n.abort(),r);try{await this.openChannel(e,t,n.signal),await this.openDownstream(t,n,r)}finally{clearTimeout(i)}}async openChannel(e,t,n){let r;try{r=await fetch(this.openUrl(t),{method:`POST`,headers:{"Content-Type":`text/plain`},body:me(e),cache:`no-store`,credentials:`omit`,signal:n})}catch(e){throw n.aborted?new S(`HTTP stream channel did not open before the mode deadline`):e}if(r.status===401||r.status===403)throw new w(`HTTP stream rejected the auth ticket (${r.status})`);if(!r.ok)throw new S(`HTTP stream could not be opened, status ${r.status}`)}async openDownstream(e,t,n){this.framer.reset();let r=new Promise((e,r)=>{let i=()=>{this.firstMessageResolver=null,r(new S(`No server message in ${n}ms`))};t.signal.addEventListener(`abort`,i,{once:!0}),this.firstMessageResolver=()=>{t.signal.removeEventListener(`abort`,i),this.firstMessageResolver=null,e()}}),i=await fetch(this.streamUrl(e),{method:`GET`,headers:{Accept:e===`sse`?`text/event-stream`:`application/octet-stream`},cache:`no-store`,credentials:`omit`,signal:t.signal});if(i.status===401||i.status===403)throw new w(`HTTP stream rejected the auth ticket (${i.status})`);if(!i.ok||!i.body)throw new S(`HTTP stream request failed with status ${i.status}`);this.runDownstreamLoop(e,i,t),await r}async runDownstreamLoop(e,t,n){let r=t;try{for(;r&&!this.isClosed&&!n.signal.aborted;){if(await this.readResponse(e,r),e!==`poll`){this.isClosed||this.handleClose(`HTTP stream ended`,!1);return}if(r=await fetch(this.streamUrl(e),{method:`GET`,headers:{Accept:`application/octet-stream`},cache:`no-store`,credentials:`omit`,signal:n.signal}),r.status===410){this.handleClose(`HTTP stream channel is gone`,!1);return}if(!r.ok||!r.body){this.handleClose(`HTTP stream poll failed with status ${r.status}`,!1);return}}}catch(e){if(n.signal.aborted||this.isClosed)return;j.debug(`HTTP stream read loop ended: ${e instanceof Error?e.message:e}`),this.handleClose(`HTTP stream read failed`,!1)}}async readResponse(e,t){let n=t.body.getReader(),r=e===`sse`?new fe:null;for(;;){let{value:e,done:t}=await n.read();if(t)return;if(e){if(r){r.push(e,e=>this.framer.push(e,e=>this.handleProtocolMessage(e)));continue}this.framer.push(e,e=>this.handleProtocolMessage(e))}}}async runSendPump(){if(!this.sendPumpRunning){this.sendPumpRunning=!0;try{for(;this.sendQueue.length>0&&!this.isClosed;){let e=this.takeBatch(),t=await fetch(this.sendUrl(),{method:`POST`,headers:{"Content-Type":`text/plain`},body:e,cache:`no-store`,credentials:`omit`});if(t.status===410){this.handleClose(`HTTP stream channel is gone`,!1);return}if(!t.ok)throw new S(`HTTP stream send failed with status ${t.status}`)}}catch(e){if(this.isClosed)return;j.warn(`HTTP stream send failed: ${e instanceof Error?e.message:e}`),this.handleClose(`HTTP stream send failed`,!1)}finally{this.sendPumpRunning=!1}}}takeBatch(){let e=0,t=0;for(;t<this.sendQueue.length;){let n=this.sendQueue[t].length;if(t>0&&e+n>1048576)break;e+=n,t++}let n=new Uint8Array(e),r=0;for(let e=0;e<t;e++)n.set(this.sendQueue[e],r),r+=this.sendQueue[e].length;return this.sendQueue.splice(0,t),n}streamUrl(e){return`${this.baseUri}${this.baseUri.includes(`?`)?`&`:`?`}sid=${this.sid}&mode=${e}`}openUrl(e){return`${this.streamUrl(e)}&open=1`}sendUrl(){return`${this.baseUri}${this.baseUri.includes(`?`)?`&`:`?`}sid=${this.sid}`}getKeepaliveResponse(){return this.keepaliveResponseMessage||=b(y(),this.sessionId),this.keepaliveResponseMessage}handleProtocolMessage(e){try{let t=r(e).opcode;if(this.firstMessageResolver&&this.firstMessageResolver(),t===v.KEEPALIVE_REQUEST){this.send(this.getKeepaliveResponse()),this.resetKeepaliveTimeout();return}this.resetKeepaliveTimeout(),this.callbacks.onProtocolMessage(e.slice())}catch(e){j.error(`Failed to process protocol message:`,e),this.callbacks.onError(e instanceof Error?e:Error(String(e)))}}handleClose(e,t){this.isClosed||this.connecting||(this.isClosed=!0,this.connected=!1,this.clearKeepaliveTimeout(),this.abortDownstream(),this.callbacks.onClose(e,t))}abortDownstream(){this.downstreamAbort&&=(this.downstreamAbort.abort(),null)}resetKeepaliveTimeout(){this.clearKeepaliveTimeout(),!(this.keepaliveTimeoutMs<=0)&&(this.keepaliveTimeout=setTimeout(()=>{j.error(`No keepalive received in ${this.keepaliveTimeoutMs}ms, closing HTTP stream`),this.callbacks.onError(new C(this.keepaliveTimeoutMs)),this.close()},this.keepaliveTimeoutMs))}clearKeepaliveTimeout(){this.keepaliveTimeout&&=(clearTimeout(this.keepaliveTimeout),null)}};function de(e){return e?[e,...ue.filter(t=>t!==e)]:ue}var fe=class{decoder=new TextDecoder;pending=``;push(e,t){this.pending+=this.decoder.decode(e,{stream:!0});let n=this.pending.indexOf(`
2
+ `);for(;n!==-1;){let e=this.pending.slice(0,n);this.pending=this.pending.slice(n+1),e.startsWith(`data: `)&&t(he(e.slice(6))),n=this.pending.indexOf(`
3
+ `)}}};function pe(){let e=new Uint8Array(16);crypto.getRandomValues(e);let t=``;for(let n of e)t+=n.toString(16).padStart(2,`0`);return t}function me(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t)}function he(e){let t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n}const N=k(`WebSocketTransport`);var ge=class{ws=null;keepaliveTimeout=null;isClosed=!1;keepaliveResponseMessage=null;firstMessageResolver=null;keepaliveTimeoutMs;connectionTimeoutMs;callbacks;sessionId;constructor(e){this.callbacks=e.callbacks,this.sessionId=e.sessionId,this.keepaliveTimeoutMs=e.keepaliveTimeoutMs,this.connectionTimeoutMs=e.connectionTimeoutMs??1e4}get isConnected(){return this.ws?.readyState===WebSocket.OPEN}async connect(e,t){this.isClosed=!1;let n=Date.now();return new Promise((r,i)=>{try{this.ws=new WebSocket(e),this.ws.binaryType=`arraybuffer`}catch(e){i(new S(`Failed to create WebSocket: ${e}`,e instanceof Error?e:void 0));return}let a=!1,o=!1,s=()=>{clearTimeout(u),this.ws&&(this.ws.onopen=null,this.ws.onerror=null,this.ws.onclose=null,this.ws.onmessage=null)},c=()=>{o||(o=!0,clearTimeout(u),this.firstMessageResolver=null,N.debug(`WebSocket connected in ${Date.now()-n}ms`),r())},l=e=>{o||(o=!0,this.firstMessageResolver=null,s(),i(e))};this.firstMessageResolver=c;let u=setTimeout(()=>{this.ws?.close(),N.warn(`WebSocket connection timeout after ${this.connectionTimeoutMs}ms`),l(new S(`WebSocket connection timeout`))},this.connectionTimeoutMs);this.ws.onopen=()=>{a=!0,this.ws.send(t),this.resetKeepaliveTimeout()},this.ws.onerror=()=>{N.debug(`WebSocket connection failed after ${Date.now()-n}ms`),l(new S(`WebSocket connection failed`))},this.ws.onclose=e=>{if(this.clearKeepaliveTimeout(),!o){l(a?new w(`WebSocket closed before first server message`):new S(`WebSocket connection closed before opening`));return}if(this.isClosed)return;let t=e.wasClean&&(e.code===1e3||e.code===1001),n=e.reason||`code=${e.code}`;this.callbacks.onClose(n,t)},this.ws.onmessage=e=>{this.handleProtocolMessage(new Uint8Array(e.data))}})}send(e){this.ws?.readyState===WebSocket.OPEN?this.ws.send(e):N.warn(`Cannot send: WebSocket not connected`)}close(){this.isClosed=!0,this.clearKeepaliveTimeout(),this.ws&&=(this.ws.close(1e3,`Client closing`),null)}getKeepaliveResponse(){return this.keepaliveResponseMessage||=b(y(),this.sessionId),this.keepaliveResponseMessage}handleProtocolMessage(e){try{let t=r(e).opcode;if(this.firstMessageResolver&&this.firstMessageResolver(),t===v.KEEPALIVE_REQUEST){this.send(this.getKeepaliveResponse()),this.resetKeepaliveTimeout();return}this.resetKeepaliveTimeout(),this.callbacks.onProtocolMessage(e)}catch(e){N.error(`Failed to process protocol message:`,e),this.callbacks.onError(e instanceof Error?e:Error(String(e)))}}resetKeepaliveTimeout(){this.clearKeepaliveTimeout(),!(this.keepaliveTimeoutMs<=0)&&(this.keepaliveTimeout=setTimeout(()=>{N.error(`No keepalive received in ${this.keepaliveTimeoutMs}ms, closing connection`),this.callbacks.onError(new C(this.keepaliveTimeoutMs)),this.close()},this.keepaliveTimeoutMs))}clearKeepaliveTimeout(){this.keepaliveTimeout&&=(clearTimeout(this.keepaliveTimeout),null)}};const P=k(`WebTransportTransport`);function F(){return typeof WebTransport<`u`}var _e=class{transport=null;stream=null;reader=null;writer=null;keepaliveTimeout=null;readLoopActive=!1;isClosed=!1;framer=new A;keepaliveResponseMessage=null;firstMessageResolver=null;firstMessageRejecter=null;keepaliveTimeoutMs;connectionTimeoutMs;callbacks;sessionId;constructor(e){this.callbacks=e.callbacks,this.sessionId=e.sessionId,this.keepaliveTimeoutMs=e.keepaliveTimeoutMs,this.connectionTimeoutMs=e.connectionTimeoutMs??1e4}get isConnected(){return this.transport!==null&&this.writer!==null}async connect(e,t){if(!F())throw new S(`WebTransport is not supported in this browser`);this.isClosed=!1;let n=Date.now(),r=new Promise((e,t)=>{this.firstMessageResolver=e,this.firstMessageRejecter=t});try{this.transport=new WebTransport(e);let i,a=new Promise((e,t)=>{i=setTimeout(()=>t(new S(`WebTransport connection timeout`)),this.connectionTimeoutMs)});try{await Promise.race([this.transport.ready,a])}catch(e){throw e instanceof S&&P.warn(`WebTransport connection timeout after ${this.connectionTimeoutMs}ms`),e}finally{clearTimeout(i)}this.transport.closed.then(()=>{this.handleClose(`Connection closed`,!0)}).catch(e=>{P.error(`WebTransport connection closed with error:`,e),this.handleClose(e instanceof Error?e.message:`Connection error`,!1)}),this.stream=await this.transport.createBidirectionalStream(),this.reader=this.stream.readable.getReader(),this.writer=this.stream.writable.getWriter(),await this.writer.write(t),this.resetKeepaliveTimeout(),this.startReadLoop();let o=Math.max(this.connectionTimeoutMs-(Date.now()-n),1),s,c=new Promise((e,t)=>{s=setTimeout(()=>t(new S(`WebTransport closed before first server message`)),o)});try{await Promise.race([r,c])}finally{clearTimeout(s)}this.firstMessageResolver=null,this.firstMessageRejecter=null,P.info(`WebTransport connected in ${Date.now()-n}ms`)}catch(e){this.firstMessageResolver=null,this.firstMessageRejecter=null,this.isClosed=!0,this.cleanup();let t=Date.now()-n;throw P.warn(`WebTransport connection failed after ${t}ms: ${e}`),new S(`Failed to connect WebTransport: ${e}`,e instanceof Error?e:void 0)}}send(e){if(!this.writer){P.warn(`Cannot send: WebTransport not connected`);return}this.writer.write(e).catch(e=>{P.error(`Failed to send protocol message:`,e),this.callbacks.onError(e instanceof Error?e:Error(String(e)))})}close(){this.isClosed=!0,this.clearKeepaliveTimeout(),this.readLoopActive=!1,this.cleanup()}async startReadLoop(){if(this.reader){this.readLoopActive=!0;try{for(;this.readLoopActive&&this.reader;){let{value:e,done:t}=await this.reader.read();if(t)break;e&&this.framer.push(e,e=>this.handleProtocolMessage(e))}this.readLoopActive&&this.handleClose(`Stream ended`,!1)}catch(e){this.readLoopActive&&(P.error(`Read loop error:`,e),this.callbacks.onError(e instanceof Error?e:Error(String(e))))}}}getKeepaliveResponse(){return this.keepaliveResponseMessage||=b(y(),this.sessionId),this.keepaliveResponseMessage}handleProtocolMessage(e){try{let t=r(e).opcode;if(this.firstMessageResolver&&this.firstMessageResolver(),t===v.KEEPALIVE_REQUEST){this.send(this.getKeepaliveResponse()),this.resetKeepaliveTimeout();return}this.resetKeepaliveTimeout(),this.callbacks.onProtocolMessage(e)}catch(e){P.error(`Failed to process protocol message:`,e),this.callbacks.onError(e instanceof Error?e:Error(String(e)))}}handleClose(e,t){if(!this.isClosed){if(this.isClosed=!0,this.clearKeepaliveTimeout(),this.readLoopActive=!1,this.cleanup(),this.firstMessageRejecter){this.firstMessageRejecter(new w(`WebTransport closed before first server message: ${e}`)),this.firstMessageResolver=null,this.firstMessageRejecter=null;return}this.callbacks.onClose(e,t)}}resetKeepaliveTimeout(){this.clearKeepaliveTimeout(),!(this.keepaliveTimeoutMs<=0)&&(this.keepaliveTimeout=setTimeout(()=>{P.error(`No keepalive received in ${this.keepaliveTimeoutMs}ms, closing connection`),this.callbacks.onError(new C(this.keepaliveTimeoutMs)),this.close()},this.keepaliveTimeoutMs))}clearKeepaliveTimeout(){this.keepaliveTimeout&&=(clearTimeout(this.keepaliveTimeout),null)}cleanup(){if(this.reader&&=(this.reader.releaseLock(),null),this.writer&&=(this.writer.releaseLock(),null),this.stream=null,this.framer.reset(),this.transport){try{this.transport.close()}catch{}this.transport=null}}};const I=k(`Channel`);var ve=class{state=`disconnected`;transport=null;config;entrypoint;constructor(e){this.config=e,this.entrypoint=e.entrypoint}get channelState(){return this.state}get opcodeGroups(){return this.entrypoint.OpcodeGroupsFromServer}get type(){return this.entrypoint.Type}get isConnected(){return this.transport?.isConnected??!1}get httpStreamMode(){return this.transport instanceof M?this.transport.activeMode:null}async connect(){if(this.state!==`disconnected`)throw Error(`Cannot connect: already in state ${this.state}`);this.setState(`connecting`);try{await this.connectTransport(),this.setState(`connected`)}catch(e){throw this.setState(`disconnected`),e}}disconnect(){this.transport&&=(this.transport.close(),null),this.setState(`disconnected`)}triggerReconnect(e){this.transport&&=(this.transport.close(),null),this.config.onClose?.(e,!1)}checkHealth(){this.state===`connected`&&this.transport&&!this.transport.isConnected&&this.handleClose(`Transport dead after tab resume`,!1)}send(e){if(!this.transport?.isConnected){I.warn(`Cannot send: channel not connected`);return}this.transport.send(e)}async connectTransport(){let e=this.entrypoint,t={sessionId:this.config.sessionId,keepaliveTimeoutMs:this.config.keepaliveTimeoutMs,connectionTimeoutMs:this.config.connectionTimeoutMs,httpStreamMode:this.config.httpStreamMode,httpStreamPreferredMode:this.config.httpStreamPreferredMode,callbacks:{onProtocolMessage:e=>this.handleProtocolMessage(e),onClose:(e,t)=>this.handleClose(e,t),onError:e=>this.handleError(e)}};switch(e.Type){case _.WebSocket:case _.WebSocketProxy:this.transport=new ge(t);break;case _.WebTransport:case _.WebTransportProxy:if(!F())throw Error(`WebTransport is not supported in this browser`);this.transport=new _e(t);break;case _.HttpStream:case _.HttpStreamProxy:this.transport=new M(t);break;default:throw Error(`Unsupported entrypoint type: ${_[e.Type]}`)}await this.transport.connect(e.Uri,e.AuthTicket)}handleProtocolMessage(n){try{let r=e(n);if(t(r)===v.CORE_ON_SERVER_STOPPING){I.debug(`Received server stopping message`),this.setState(`stopped`),this.transport?.close();return}this.config.onProtocolMessage?.(r)}catch(e){I.error(`Failed to handle protocol message:`,e),this.config.onError?.(e instanceof Error?e:Error(String(e)))}}handleClose(e,t){this.transport=null,this.config.onClose?.(e,t)}handleError(e){this.config.onError?.(e),e instanceof C&&this.handleClose(`Keepalive timeout`,!1)}setState(e){this.state!==e&&(this.state=e,this.config.onStateChange?.(e))}};const L=k(`ChannelManager`);var ye=class{channels=new Map;activeType=null;state=`idle`;reconnectAttempts=0;shouldReconnect=!0;entrypoints=[];abortController=null;connectionTimeoutMs;stabilityTimer=null;config;constructor(e){this.config=e}get managerState(){return this.state}get activeHttpStreamMode(){for(let e of this.channels.values()){let t=e.httpStreamMode;if(t)return t}return null}get activeEndpointType(){return this.activeType}async connect(e,t){if(this.state!==`idle`&&this.state!==`offline`)throw Error(`Cannot connect: already in state ${this.state}`);if(this.entrypoints=e,this.shouldReconnect=!0,this.reconnectAttempts=0,this.abortController=new AbortController,t?.retry){this.attemptReconnect();return}await this.connectInternal()}disconnect(){this.shouldReconnect=!1,this.abortController?.abort(),this.abortController=null,this.disconnectAll(),this.setState(`idle`)}sendProtocolMessage(e){let t=n(e);for(let[n,r]of this.channels)if(n&t){r.send(e);return}this.state===`connected`&&L.warn(`No channel found for message`)}sendToAll(e){for(let t of this.channels.values())t.send(e)}checkHealth(){if(this.state===`connected`)for(let e of this.channels.values())e.checkHealth()}triggerReconnect(e){if(this.state===`connected`){L.debug(`Forcing reconnect: ${e}`);for(let t of this.channels.values())t.triggerReconnect(e)}}async connectInternal(e=!1){this.setState(`connecting`);let t=this.entrypoints.filter(e=>e.Type!==_.WebRTC),n=this.groupByType(t);if(n.size===0)throw this.setState(`offline`),Error(`No entrypoints available`);let r;if(this.config.orderedEndpointTypes!==void 0){let e=new Set(n.keys());r=this.config.orderedEndpointTypes.filter(t=>e.has(t))}else r=this.config.endpointSelector?this.config.endpointSelector.getOrderedTypes(n):Array.from(n.keys());if(r.length===0)throw this.setState(`offline`),new E(null,null,[...n.keys()].map(e=>_[e]));this.connectionTimeoutMs=r.length>1?5e3:1e4,L.debug(`Endpoint types to try: [${r.map(e=>_[e]).join(`, `)}], transport timeout: ${this.connectionTimeoutMs}ms`);for(let e of r){if(!this.shouldReconnect)return;let t=n.get(e),r=Date.now();L.debug(`Trying ${_[e]} (${t.length} channel(s))`);try{await this.connectAllChannels(t),this.config.endpointSelector?.rememberWorkingType(e),this.config.onRememberWorkingType?.(e),this.activeType=e,L.debug(`Connected via ${_[e]} in ${Date.now()-r}ms`),this.setState(`connected`),this.startStabilityTimer();return}catch(t){L.warn(`Failed to connect using ${_[e]} after ${Date.now()-r}ms: ${t instanceof Error?t.message:t}`);let i=this.channels.size>0;if(this.disconnectAll(),t instanceof w)throw t;if(i&&this.config.onRefreshEntrypoints)try{L.info(`Partial connection detected, refreshing entrypoints`);let e=await this.config.onRefreshEntrypoints();this.entrypoints=e.entrypoints,this.config.sessionId=e.sessionId;let t=e.entrypoints.filter(e=>e.Type!==_.WebRTC),r=this.groupByType(t);for(let[e,t]of r)n.set(e,t)}catch(e){L.warn(`Failed to refresh entrypoints: ${e}`)}}}throw e||this.setState(`offline`),Error(`Failed to connect using any endpoint type`)}async connectAllChannels(e){if(e.length===0)throw Error(`No entrypoints to connect`);let t=(await Promise.allSettled(e.map(e=>this.connectChannel(e)))).filter(e=>e.status===`rejected`);if(t.length>0){let e=t.map(e=>e.reason instanceof Error?e.reason.message:String(e.reason));throw t.some(e=>e.reason instanceof w)?new w(e.join(`, `)):Error(e.join(`, `))}}async connectChannel(e){let t=new ve({entrypoint:e,sessionId:this.config.sessionId,keepaliveTimeoutMs:this.config.keepaliveTimeoutMs,connectionTimeoutMs:this.connectionTimeoutMs,httpStreamMode:this.config.httpStreamMode,httpStreamPreferredMode:this.config.httpStreamPreferredMode,onProtocolMessage:e=>{this.config.onProtocolMessage?.(e)},onStateChange:t=>{this.handleChannelStateChange(e.OpcodeGroupsFromServer,t)},onClose:(t,n)=>{this.handleChannelClose(e.OpcodeGroupsFromServer,t,n)},onError:e=>{this.config.onError?.(e)}});await t.connect(),this.channels.set(e.OpcodeGroupsFromServer,t)}groupByType(e){let t=new Map;for(let n of e){let e=t.get(n.Type)??[];e.push(n),t.set(n.Type,e)}return t}handleChannelStateChange(e,t){t===`stopped`&&(this.shouldReconnect=!1,this.disconnectAll(),this.setState(`stopped`))}handleChannelClose(e,t,n){this.state!==`idle`&&this.state!==`stopped`&&this.state!==`offline`&&this.channels.has(e)&&this.state===`connected`&&(L.warn(`Channel closed unexpectedly, attempting reconnect`),this.disconnectAll(),this.attemptReconnect())}async attemptReconnect(){if(this.shouldReconnect){if(!le()){L.warn(`Retry disabled via ikon-retry=false, skipping reconnect`),this.setState(`offline`),this.config.onError?.(new T(0));return}if(this.reconnectAttempts>=this.config.maxReconnectAttempts){L.warn(`Max reconnect attempts (${this.config.maxReconnectAttempts}) reached`),this.setState(`offline`),this.config.onError?.(new T(this.config.maxReconnectAttempts));return}if(this.setState(`reconnecting`),this.reconnectAttempts++,this.reconnectAttempts>1){L.info(`Reconnecting in ${this.config.reconnectBackoffMs}ms (attempt ${this.reconnectAttempts}/${this.config.maxReconnectAttempts})`);try{await ne(this.config.reconnectBackoffMs,this.abortController?.signal)}catch{return}}else L.info(`Reconnecting immediately (attempt ${this.reconnectAttempts}/${this.config.maxReconnectAttempts})`);if(this.shouldReconnect)try{await this.connectInternal(!0)}catch(e){if(e instanceof w){L.warn(`Auth rejected during reconnect, stopping retries and signaling full re-auth`),this.config.onError?.(e),this.setState(`offline`);return}if(e instanceof E){L.warn(`${e.message} Not retrying`),this.config.onError?.(e),this.setState(`offline`);return}await this.attemptReconnect()}}}disconnectAll(){for(let e of this.channels.values())e.disconnect();this.channels.clear(),this.activeType=null}setState(e){this.state!==e&&(this.state===`connected`&&e!==`connected`&&this.clearStabilityTimer(),this.state=e,this.config.onStateChange?.(e))}startStabilityTimer(){this.clearStabilityTimer(),this.stabilityTimer=setTimeout(()=>{this.stabilityTimer=null,this.state===`connected`&&(this.reconnectAttempts=0)},5e3)}clearStabilityTimer(){this.stabilityTimer&&=(clearTimeout(this.stabilityTimer),null)}};const R=k(`ProtocolWorker`),z=(e,t)=>{self.postMessage(e,t??[])};let B=null,V=null,H=null,U,W=null;const G=[],K=[],q=new Map,J=[],Y=[],X=new Map,Z=[];function Q(){try{B?.disconnect()}catch(e){R.warn(`Failed to disconnect channel manager: ${e}`)}B=null;for(let e=0;e<K.length;e++)try{K[e].port.close()}catch{}G.length=0,K.length=0,q.clear();for(let e=0;e<Y.length;e++)try{Y[e].port.close()}catch{}J.length=0,Y.length=0,X.clear()}function $(e){let t=e instanceof Error?e:Error(String(e));z({type:`error`,error:{name:t.name,message:t.message,stack:t.stack}})}function be(){let e=0;for(let t=0;t<K.length;t++)e|=K[t].opcodeGroupsMask;return e}function xe(e){if(U===void 0)return!0;let t=n(e);return(t&U)!==0||(t&be())!==0}function Se(e){Z.length=0;for(let t=0;t<K.length;t++){let n=K[t];(n.opcodeGroupsMask&e)!==0&&Z.push(n.port)}return Z}function Ce(e,t){return(n(e)&t)!==0}function we(t,n){if(!B||!n||typeof n!=`object`)return;let r=n;if(!(r.type!==`send`||!(r.message instanceof ArrayBuffer)))try{let n=e(new Uint8Array(r.message));if(!Ce(n,t))return;B.sendProtocolMessage(n),W&&W.postMessage({direction:`sent`,message:Array.from(n)})}catch(e){$(e)}}async function Te(e){Q(),B=new ye({sessionId:e.sessionId,keepaliveTimeoutMs:e.keepaliveTimeoutMs,reconnectBackoffMs:e.reconnectBackoffMs,maxReconnectAttempts:e.maxReconnectAttempts,orderedEndpointTypes:e.orderedEndpointTypes,httpStreamMode:e.httpStreamMode,httpStreamPreferredMode:e.httpStreamPreferredMode,webRtcEnabled:e.webRtcEnabled,onStateChange:e=>{z({type:`state`,state:e,activeType:B?.activeEndpointType??void 0,httpStreamMode:B?.activeHttpStreamMode??void 0})},onRememberWorkingType:()=>{z({type:`state`,state:B?.managerState??`idle`,activeType:B?.activeEndpointType??void 0,httpStreamMode:B?.activeHttpStreamMode??void 0})},onError:e=>{$(e)},onRefreshEntrypoints:()=>new Promise((e,t)=>{V=e,H=t,z({type:`refreshEntrypoints`})}),onProtocolMessage:e=>{W&&(W.postMessage({direction:`received`,message:Array.from(e)}),t(e)===v.ANALYTICS_LOGS&&W.postMessage({type:`serverLogs`,message:Array.from(e)}));let i=n(e),a=xe(e),o=Se(i);if(!(!a&&o.length===0))try{let t=r(e),n=e.buffer instanceof ArrayBuffer&&e.byteOffset===0&&e.byteLength===e.buffer.byteLength,i=o.length>0;if(i&&!a&&o.length===1&&n){let n=e.buffer;o[0].postMessage({type:`protocol`,message:n,headers:t},[n]);return}if(!i&&a&&n){let n=e.buffer;z({type:`protocol`,message:n,headers:t},[n]);return}if(i&&n){let n=[];for(let t=1;t<o.length;t++)n.push(e.slice().buffer);let r=a?e.slice().buffer:null,i=e.buffer;o[0].postMessage({type:`protocol`,message:i,headers:t},[i]);for(let e=1;e<o.length;e++)o[e].postMessage({type:`protocol`,message:n[e-1],headers:t},[n[e-1]]);r&&z({type:`protocol`,message:r,headers:t},[r]);return}if(i)for(let n of o){let r=e.slice().buffer;n.postMessage({type:`protocol`,message:r,headers:t},[r])}if(a){let n=e.slice().buffer;z({type:`protocol`,message:n,headers:t},[n])}}catch(e){$(e)}}}),await B.connect(e.entrypoints,{retry:e.retry})}self.addEventListener(`message`,t=>{let i=t.data;if(i.type===`connect`){Te(i).catch(e=>{R.error(`Failed to connect: ${e}`),$(e),Q()});return}if(i.type===`disconnect`){Q(),z({type:`state`,state:`idle`});return}if(i.type===`send`){if(!B)return;try{let t=e(new Uint8Array(i.message));B.sendProtocolMessage(t),W&&W.postMessage({direction:`sent`,message:Array.from(t)})}catch(e){$(e)}return}if(i.type===`setInterest`){U=i.opcodeGroupsMask;return}if(i.type===`enableDevtools`){i.enabled&&!W?W=new BroadcastChannel(`ikon:devtools`):!i.enabled&&W&&(W.close(),W=null);return}if(i.type===`setLogLevel`){ie(i.level);return}if(i.type===`checkHealth`){B?.checkHealth();return}if(i.type===`triggerReconnect`){B?.triggerReconnect(i.reason);return}if(i.type===`refreshedEntrypoints`){V&&(V({entrypoints:i.entrypoints,sessionId:i.sessionId}),V=null,H=null);return}if(i.type===`refreshEntrypointsFailed`){H&&=(H(Error(`Failed to refresh entrypoints`)),V=null,null);return}if(i.type===`forwardToPorts`){try{let t=e(new Uint8Array(i.message)),a=Se(n(t));if(a.length>0){let e=r(t);for(let n of a){let r=t.slice().buffer;n.postMessage({type:`protocol`,message:r,headers:e},[r])}}}catch(e){$(e)}return}if(i.type===`attachPort`){try{i.port.start?.()}catch{}let e=G.length;G.push(i.portId),K.push({port:i.port,opcodeGroupsMask:i.opcodeGroupsMask}),q.set(i.portId,e);return}if(i.type===`detachPort`){let e=q.get(i.portId);if(e!==void 0){let t=K[e];try{t.port.close()}catch{}let n=G.length-1;if(e!==n){let t=G[n];G[e]=t,K[e]=K[n],q.set(t,e)}G.length--,K.length--,q.delete(i.portId)}return}if(i.type===`attachSendPort`){let e=X.get(i.portId);if(e!==void 0){let t=Y[e];try{t.port.close()}catch{}let n=J.length-1;if(e!==n){let t=J[n];J[e]=t,Y[e]=Y[n],X.set(t,e)}J.length--,Y.length--,X.delete(i.portId)}let t={port:i.port,opcodeGroupsMask:i.opcodeGroupsMask},n=J.length;J.push(i.portId),Y.push(t),X.set(i.portId,n);try{t.port.start?.()}catch{}t.port.addEventListener(`message`,e=>{we(t.opcodeGroupsMask,e.data)});return}if(i.type===`detachSendPort`){let e=X.get(i.portId);if(e!==void 0){let t=Y[e];try{t.port.close()}catch{}let n=J.length-1;if(e!==n){let t=J[n];J[e]=t,Y[e]=Y[n],X.set(t,e)}J.length--,Y.length--,X.delete(i.portId)}return}});
@@ -1,5 +1,6 @@
1
1
  import { EndpointSelector } from '../client/endpoint-selector';
2
2
  import { Entrypoint, EntrypointType, ProtocolMessage } from '../../shared/protocol/src/index.ts';
3
+ import { HttpStreamMode } from '../transport/transport';
3
4
  /**
4
5
  * ChannelManager state.
5
6
  */
@@ -33,6 +34,15 @@ export interface ChannelManagerConfig {
33
34
  * Useful for worker environments where localStorage might be unavailable.
34
35
  */
35
36
  orderedEndpointTypes?: EntrypointType[];
37
+ /**
38
+ * Pins the HTTP stream transport to one downstream encoding. Read from `?ikon-transport=http-<encoding>`
39
+ * on the main thread and forwarded here, since this manager runs inside the protocol worker.
40
+ */
41
+ httpStreamMode?: HttpStreamMode;
42
+ /**
43
+ * The encoding to start the HTTP stream's ladder at, learned from a previous connection.
44
+ */
45
+ httpStreamPreferredMode?: HttpStreamMode;
36
46
  /**
37
47
  * Called when a working endpoint type is discovered.
38
48
  * Typically used by the host to persist endpoint preference.
@@ -94,6 +104,8 @@ export declare class ChannelManager {
94
104
  /**
95
105
  * Get the active endpoint type.
96
106
  */
107
+ /** The encoding the active HTTP stream channel settled on, or null when none is HTTP. */
108
+ get activeHttpStreamMode(): HttpStreamMode | null;
97
109
  get activeEndpointType(): EntrypointType | null;
98
110
  /**
99
111
  * Connect to the server using the provided entrypoints.
@@ -1,4 +1,5 @@
1
1
  import { Entrypoint, EntrypointType, ProtocolMessage } from '../../shared/protocol/src/index.ts';
2
+ import { HttpStreamMode } from '../transport/transport';
2
3
  /**
3
4
  * Channel state.
4
5
  */
@@ -24,6 +25,14 @@ export interface ChannelConfig {
24
25
  * If not specified, transports use their own defaults.
25
26
  */
26
27
  connectionTimeoutMs?: number;
28
+ /**
29
+ * Pins the HTTP stream transport to one downstream encoding. See `TransportConfig`.
30
+ */
31
+ httpStreamMode?: HttpStreamMode;
32
+ /**
33
+ * The encoding to start the HTTP stream's ladder at, learned from a previous connection.
34
+ */
35
+ httpStreamPreferredMode?: HttpStreamMode;
27
36
  /**
28
37
  * Callback when a protocol message is received.
29
38
  */
@@ -74,6 +83,13 @@ export declare class Channel {
74
83
  * Check if transport is connected.
75
84
  */
76
85
  get isConnected(): boolean;
86
+ /**
87
+ * The encoding an HTTP stream transport settled on, or null for every other transport.
88
+ *
89
+ * Read back out rather than reported through a callback so the `Transport` interface stays free of
90
+ * anything specific to one implementation.
91
+ */
92
+ get httpStreamMode(): HttpStreamMode | null;
77
93
  /**
78
94
  * Connect to the entrypoint.
79
95
  */
@@ -1,4 +1,5 @@
1
1
  import { Entrypoint, EntrypointType } from '../../shared/protocol/src/index.ts';
2
+ import { HttpStreamMode } from '../transport/transport';
2
3
  import { LocalConfig } from './ikon-client-config';
3
4
  /**
4
5
  * Proxy connection mode.
@@ -58,13 +59,16 @@ export declare class EndpointSelector {
58
59
  private readonly _proxyMode;
59
60
  private readonly _websocket;
60
61
  private readonly _webtransport;
62
+ private readonly _httpstream;
61
63
  private _connectTier;
62
64
  private workingEndpointType;
65
+ private workingHttpStreamMode;
63
66
  constructor(config: {
64
67
  local?: LocalConfig;
65
68
  proxyMode?: ProxyMode;
66
69
  websocket?: boolean;
67
70
  webtransport?: boolean;
71
+ httpstream?: boolean;
68
72
  });
69
73
  get proxyMode(): ProxyMode;
70
74
  /** The connect tier last known to work. */
@@ -78,6 +82,20 @@ export declare class EndpointSelector {
78
82
  get proxyPreferred(): boolean;
79
83
  /** The endpoint type last known to work, or null when nothing has been learned yet. */
80
84
  get rememberedType(): EntrypointType | null;
85
+ /**
86
+ * The HTTP stream encoding last known to work, or null when none has been learned.
87
+ *
88
+ * Learned separately from the endpoint type because it answers a different question: the type says
89
+ * which transport the network permits, this says which shape of response survives the middlebox in
90
+ * the path. Without it a client on a proxy that buffers re-pays the whole encoding walk — two
91
+ * full mode timeouts — on every connect and every reconnect.
92
+ *
93
+ * Kept here rather than in the transport because the transport runs in the protocol worker, which
94
+ * has no storage to keep it in.
95
+ */
96
+ get rememberedHttpStreamMode(): HttpStreamMode | null;
97
+ /** The encoding an HTTP stream connection settled on. */
98
+ rememberHttpStreamMode(mode: HttpStreamMode): void;
81
99
  /**
82
100
  * The connect URL that just answered. Authoritative — it is the only thing that can distinguish
83
101
  * the two proxied tiers.
@@ -135,6 +153,15 @@ export declare class EndpointSelector {
135
153
  * rather than re-running on every connection.
136
154
  */
137
155
  recordFasterTypesUnreachable(): void;
156
+ /**
157
+ * Apply the per-transport-family overrides.
158
+ *
159
+ * Any family explicitly turned **on** makes the filter a whitelist — asking for one transport means
160
+ * asking for only that one. Otherwise any family turned **off** is removed and the rest stay. With
161
+ * nothing set, nothing is filtered.
162
+ */
163
+ private clearHttpStreamMode;
164
+ private loadHttpStreamMode;
138
165
  private filterByTransport;
139
166
  private revalidationAgeMs;
140
167
  private loadRememberedType;
@@ -344,7 +344,7 @@ export interface IkonClientConfig {
344
344
  /**
345
345
  * Force WebSocket transport only. When true, only WebSocket (and WebSocketProxy)
346
346
  * endpoint types are used. When false, WebSocket types are excluded.
347
- * Can be overridden by the `?ikon-websocket=` query parameter.
347
+ * Overridden per session by `?ikon-transport=ws`.
348
348
  */
349
349
  websocket?: boolean;
350
350
  /**
@@ -356,9 +356,20 @@ export interface IkonClientConfig {
356
356
  * WebSocket. When left unset or set to `false`, WebTransport types are excluded
357
357
  * and the SDK uses WebSocket / WebSocketProxy only.
358
358
  *
359
- * Can be overridden by the `?ikon-webtransport=true|false` query parameter.
359
+ * Overridden per session by `?ikon-transport=wt`.
360
360
  */
361
361
  webtransport?: boolean;
362
+ /**
363
+ * Force the HTTP stream transport only (`true`), or exclude it (`false`).
364
+ *
365
+ * Unset by default, which leaves it as the last rung of the transport ladder: it is tried only
366
+ * once WebSocket and WebTransport have failed, and it is the one that survives a network which
367
+ * permits HTTPS to the app's origin but blocks the WebSocket upgrade.
368
+ *
369
+ * Overridden per session by `?ikon-transport=http`, whose `http-binary` / `http-sse` /
370
+ * `http-poll` forms also pin the downstream encoding.
371
+ */
372
+ httpstream?: boolean;
362
373
  /**
363
374
  * Pin the connect tier. When true, only the on-host proxy on 443 is used, and only proxy endpoint
364
375
  * types with it. When false, proxy types are excluded. `'lb'` pins the same-origin stream tier
@@ -1,4 +1,4 @@
1
- import { GlobalState, ProtocolMessage } from '../../shared/protocol/src/index.ts';
1
+ import { EntrypointType, GlobalState, ProtocolMessage } from '../../shared/protocol/src/index.ts';
2
2
  import { WebRTCSignaling } from '../webrtc';
3
3
  import { FunctionRegistry } from '../functions/function-registry';
4
4
  import { ReactiveRegistry } from '../reactive/reactive-registry';
@@ -103,6 +103,9 @@ export declare class IkonClient {
103
103
  private _connectUrl;
104
104
  private _brandingRequired;
105
105
  private currentState;
106
+ private _activeEndpointType;
107
+ private _fallbackTransportWarned;
108
+ private readonly httpStreamMode;
106
109
  private _connectStarted;
107
110
  private connectionTimer;
108
111
  private messageSubscribers;
@@ -143,6 +146,10 @@ export declare class IkonClient {
143
146
  private _channelsConnected;
144
147
  private _joinedHandled;
145
148
  private _environmentTrackingSetup;
149
+ private _environmentTrackingCleanup;
150
+ private _logSenderStarted;
151
+ private readonly _siblings;
152
+ private _tokenOwner;
146
153
  private readonly _functionRegistry;
147
154
  private readonly _reactiveRegistry;
148
155
  private unregisterBrowserFunctions;
@@ -335,6 +342,14 @@ export declare class IkonClient {
335
342
  * Get the current connection state.
336
343
  */
337
344
  get connectionState(): ConnectionState;
345
+ /**
346
+ * Which entrypoint type is carrying the session, or null before one is.
347
+ *
348
+ * Reported by the protocol worker, which owns the channels — so it is the only way the page can
349
+ * tell which transport it ended up on, and the learned preference is not a substitute: a local run
350
+ * never records one.
351
+ */
352
+ get activeEndpointType(): EntrypointType | null;
338
353
  /**
339
354
  * Get the function registry for registering custom functions.
340
355
  */
@@ -365,6 +380,10 @@ export declare class IkonClient {
365
380
  * THIS client's connection, and a sibling reporting through them corrupts the owner's
366
381
  * state (a closed media leg would paint the app's offline overlay). Pass them in
367
382
  * `overrides` to observe the sibling.
383
+ *
384
+ * The credential it carries is a snapshot taken now. A client built from it keeps that copy, so on
385
+ * a long-lived page it goes stale as this client's token is renewed — use {@link createSibling} to
386
+ * have renewals follow the sibling.
368
387
  */
369
388
  deriveConfig(parameters: Record<string, string>, overrides?: Partial<IkonClientConfig>): IkonClientConfig;
370
389
  /**
@@ -376,6 +395,30 @@ export declare class IkonClient {
376
395
  * Execute the connection flow with the provided authentication function.
377
396
  */
378
397
  private executeConnection;
398
+ /**
399
+ * Replace the credential that a later authenticate will present.
400
+ *
401
+ * A browser access token is short-lived and renewed on a timer well before it expires, and the
402
+ * renewal is the same user with a fresher token — not a different connection. Handing it to the
403
+ * live client keeps the connection up and leaves the next authenticate (a soft reconnect, a
404
+ * resume from sleep, a retry) presenting a credential that is still valid, which is the whole
405
+ * point of renewing ahead of expiry. Rebuilding the client instead would drop a working session
406
+ * every renewal period for no reason.
407
+ *
408
+ * The token must belong to the same user. A different one needs a new client: this connection was
409
+ * resolved from the old identity, and carrying on with someone else's credential would present it
410
+ * on a session that was never theirs.
411
+ */
412
+ updateAuthToken(token: string): void;
413
+ /**
414
+ * Open a sibling connection to the same deployment, built from {@link deriveConfig}, and keep its
415
+ * credential in step with this one. A page uses this to run a second session next to its app
416
+ * connection — a media leg to a cell room, say — which then outlives several token renewals.
417
+ *
418
+ * The sibling is released when it disconnects, which `useSiblingClient` does on unmount and on any
419
+ * change of parameters.
420
+ */
421
+ createSibling(parameters: Record<string, string>, overrides?: Partial<IkonClientConfig>): IkonClient;
379
422
  /**
380
423
  * Disconnect from the server.
381
424
  */
@@ -570,7 +613,45 @@ export declare class IkonClient {
570
613
  private disconnectProtocol;
571
614
  private getServerKeepaliveTimeoutMs;
572
615
  private groupEntrypointsByType;
616
+ /**
617
+ * Tell the developer — and through them, whoever runs the network — that this session is on the
618
+ * fallback transport and why it is slower than it should be.
619
+ *
620
+ * At `warn` rather than `debug` because it is not a diagnostic: the app works, so nothing else
621
+ * will ever say that every interaction is costing a round trip it does not need to, and the only
622
+ * fix is a change to the network that no one here can make. It also reaches the SDK's log sink,
623
+ * so how often real sessions land here stops being a guess.
624
+ *
625
+ * Once per session. A reconnect lands on the same transport for the same reason, and repeating it
626
+ * on every network blip would train people to filter it out.
627
+ */
628
+ private warnAboutFallbackTransport;
629
+ /**
630
+ * The ask itself, worded for whoever runs the network rather than for whoever reads the console.
631
+ *
632
+ * The app's own address is the whole of it. The stream tier opens its WebSocket there too, so an
633
+ * allowlist covering it covers every rung that matters — and naming the per-session hostnames
634
+ * behind the other tiers would hand an administrator a list that changes as capacity does.
635
+ */
636
+ private fallbackTransportMessage;
637
+ /**
638
+ * Learn the encoding a connection settled on, unless the URL chose it.
639
+ *
640
+ * A pinned encoding working says nothing about whether a faster one would have, so recording it
641
+ * would turn a one-off diagnostic into a preference that outlives the session that asked for it —
642
+ * the same reason a forced proxy mode persists nothing.
643
+ */
644
+ private rememberHttpStreamModeUnlessPinned;
573
645
  private computeOrderedEndpointTypes;
646
+ /**
647
+ * Fail the connect when `?ikon-transport` / `?ikon-proxy` pin a combination the server did not
648
+ * offer — `?ikon-proxy=lb&ikon-transport=wt`, where the stream tier advertises no WebTransport.
649
+ *
650
+ * A pin exists to make one path measurable, so widening back to whatever the server did offer
651
+ * would report success for a session that measured a different path — the worst possible answer,
652
+ * because nothing about it looks wrong. Failing is the only honest one.
653
+ */
654
+ private assertPinnedTransportIsAvailable;
574
655
  private revalidateEndpointPreference;
575
656
  private updateWorkerInterestMask;
576
657
  /**
@@ -13,12 +13,7 @@ export declare const IKON_AUTH_URL_DEV = "https://auth.dev.ikonai.com";
13
13
  * @deprecated Use deriveAuthUrl() instead
14
14
  */
15
15
  export declare const IKON_AUTH_BASE_URL = "https://auth.ikonai.com";
16
- /**
17
- * Same-origin auth base (`<origin>/ikon/auth`) for deployed cloud apps. Used as the automatic
18
- * fallback when the cross-origin auth host is unreachable (e.g. an old device that doesn't trust
19
- * its TLS cert), and — when `?ikon-auth=same` is set — as the primary auth URL. Returns null off
20
- * cloud / non-browser. Requires the app LB to route `/ikon/auth/* → auth backend`.
21
- */
16
+ /** Same-origin auth base (`<origin>/ikon/auth`), or null when same origin does not apply. */
22
17
  export declare function getSameOriginAuthUrl(): string | null;
23
18
  /**
24
19
  * Resolve the stream tier's connect path (`/ikon/stream/connect?…`) against the page origin.
@@ -32,7 +27,7 @@ export declare function getSameOriginAuthUrl(): string | null;
32
27
  export declare function getSameOriginStreamUrl(streamPath: string): string | null;
33
28
  /**
34
29
  * Get backend URL from BackendType.
35
- * Defaults to same-origin /ikon/api on deployed apps; honors ?ikon-api=false to opt out.
30
+ * Defaults to same-origin /ikon/api on deployed apps; honors ?ikon-same-origin=false to opt out.
36
31
  */
37
32
  export declare function getBackendUrl(backendType?: BackendType): string;
38
33
  /**
@@ -40,7 +35,7 @@ export declare function getBackendUrl(backendType?: BackendType): string;
40
35
  * Priority:
41
36
  * 1. Explicit override (e.g. from config)
42
37
  * 2. VITE_IKON_BACKEND_URL env var (set by .NET server during local dev)
43
- * 3. Cloud environment, not opted out via ?ikon-api=false → same-origin /ikon/api (default)
38
+ * 3. Cloud environment, not opted out via ?ikon-same-origin=false → same-origin /ikon/api (default)
44
39
  * 4. Local environment (localhost, LAN IPs) → IKON_BACKEND_URL_DEV
45
40
  * 5. Platform hostname inference
46
41
  * 6. Env discovered by a previous deriveAuthUrl() call on this page
@@ -111,7 +106,7 @@ export declare function isCloudEnvironment(): boolean;
111
106
  * Get the initial path from the browser URL — path plus query, since the app owns all of it
112
107
  * and deep links legitimately carry state in query parameters (e.g. a landing page's
113
108
  * ?prompt= surviving an OAuth round-trip into the app's URL restore). SDK-internal
114
- * ikon-* parameters (ikon-server-url, ikon-signed-out, ikon-snapshot, …) are transport
109
+ * ikon-* parameters (ikon-connect, ikon-signed-out, ikon-snapshot, …) are transport
115
110
  * concerns, not app state, and are stripped. Returns "/" when there is no path.
116
111
  */
117
112
  export declare function getInitialPath(): string;
@@ -125,3 +120,12 @@ export declare function getInitialPath(): string;
125
120
  * so callers must handle an absent value rather than assume a parseable URL.
126
121
  */
127
122
  export declare function getInitialUrl(): string;
123
+ /**
124
+ * The current URL with the `ikon-session` deep link dropped. Loading it starts a fresh session
125
+ * instead of rejoining the named one, which is the only way out once that session has ended — a
126
+ * plain reload rejoins the same dead session and fails the same way. Every other parameter is
127
+ * still live and is kept.
128
+ *
129
+ * Returns "" off-browser, so callers must handle an absent value rather than navigate to it.
130
+ */
131
+ export declare function getUrlWithoutSession(): string;
package/errors/index.d.ts CHANGED
@@ -72,6 +72,17 @@ export declare class AccessDeniedError extends AuthenticationError {
72
72
  readonly reason: string;
73
73
  constructor(message: string, reason: string);
74
74
  }
75
+ /**
76
+ * Error thrown when the backend rejects the credential the connect flow presented (HTTP 401).
77
+ *
78
+ * Terminal — the SDK must not retry. The same token is what every later attempt would present, so
79
+ * retrying cannot change the answer, and the reconnect loop above these retries turns "cannot
80
+ * change the answer" into a rejected request every few seconds for as long as the tab stays open.
81
+ * Signing in again is the only thing that helps, which is a decision for the host application.
82
+ */
83
+ export declare class CredentialRejectedError extends AuthenticationError {
84
+ constructor(message: string);
85
+ }
75
86
  /**
76
87
  * Error thrown when `?ikon-session=<hash>` names a session that is not live (HTTP 404).
77
88
  * Terminal — the SDK must not retry, and must not fall back to starting a fresh session: a
@@ -110,3 +121,19 @@ export declare class BrowserNotSupportedError extends ConnectionError {
110
121
  readonly missingFeatures: string[];
111
122
  constructor(missingFeatures: string[]);
112
123
  }
124
+ /**
125
+ * Error thrown when `?ikon-transport` and/or `?ikon-proxy` pin a combination no offered entrypoint
126
+ * satisfies — e.g. `?ikon-proxy=lb&ikon-transport=wt`, where the stream tier advertises no
127
+ * WebTransport.
128
+ *
129
+ * Terminal, and terminal for the same reason {@link SessionNotFoundError} is: the pin exists to make
130
+ * one path testable, so quietly connecting over a different transport or a different tier reports
131
+ * success for a session that measured nothing. Retrying cannot help either — the offered set is
132
+ * fixed for this connect — so it must not burn the reconnect budget.
133
+ */
134
+ export declare class NoMatchingEndpointTypeError extends ConnectionError {
135
+ readonly pinnedTransport: string | null;
136
+ readonly pinnedTier: string | null;
137
+ readonly offeredTypes: string[];
138
+ constructor(pinnedTransport: string | null, pinnedTier: string | null, offeredTypes: string[]);
139
+ }
@@ -815,7 +815,7 @@ var pe = /* @__PURE__ */ function(e) {
815
815
  }({}), ge = /* @__PURE__ */ function(e) {
816
816
  return e[e.Unknown = 0] = "Unknown", e[e.Backend = 2] = "Backend", e[e.Server = 4] = "Server", e[e.Plugin = 8] = "Plugin", e[e.Browser = 16] = "Browser", e[e.Native = 32] = "Native", e;
817
817
  }({}), _e = /* @__PURE__ */ function(e) {
818
- return e[e.None = 0] = "None", e[e.WebSocket = 1] = "WebSocket", e[e.WebSocketProxy = 2] = "WebSocketProxy", e[e.WebTransport = 4] = "WebTransport", e[e.WebTransportProxy = 8] = "WebTransportProxy", e[e.Tcp = 16] = "Tcp", e[e.TcpProxy = 32] = "TcpProxy", e[e.Https = 64] = "Https", e[e.WebRTC = 128] = "WebRTC", e[e.TcpTls = 256] = "TcpTls", e[e.Udp = 512] = "Udp", e[e.UdpDtls = 1024] = "UdpDtls", e;
818
+ return e[e.None = 0] = "None", e[e.WebSocket = 1] = "WebSocket", e[e.WebSocketProxy = 2] = "WebSocketProxy", e[e.WebTransport = 4] = "WebTransport", e[e.WebTransportProxy = 8] = "WebTransportProxy", e[e.Tcp = 16] = "Tcp", e[e.TcpProxy = 32] = "TcpProxy", e[e.Https = 64] = "Https", e[e.WebRTC = 128] = "WebRTC", e[e.TcpTls = 256] = "TcpTls", e[e.Udp = 512] = "Udp", e[e.UdpDtls = 1024] = "UdpDtls", e[e.HttpStream = 2048] = "HttpStream", e[e.HttpStreamProxy = 4096] = "HttpStreamProxy", e;
819
819
  }({}), ve = /* @__PURE__ */ function(e) {
820
820
  return e[e.None = 0] = "None", e[e.SendBackToSender = 1] = "SendBackToSender", e[e.Delayable = 2] = "Delayable", e[e.SendToUser = 4] = "SendToUser", e[e.Compressed = 8] = "Compressed", e[e.Unreliable = 16] = "Unreliable", e;
821
821
  }({}), ye = /* @__PURE__ */ function(e) {
package/index.d.ts CHANGED
@@ -6,7 +6,7 @@ export { isConnecting, isConnected, isOffline, isError } from './client/connecti
6
6
  export { ChannelManager, type ChannelManagerConfig, type ChannelManagerState } from './channel/channel-manager';
7
7
  export { Channel, type ChannelConfig, type ChannelState } from './channel/channel';
8
8
  export { EndpointSelector, orderConnectTiers, CONNECT_TIER_LADDER, type ConnectTier, type ProxyMode } from './client/endpoint-selector';
9
- export { ConnectionError, AuthenticationError, TransportError, KeepaliveTimeoutError, AuthRejectedError, MaxRetriesExceededError, ProvisioningTimeoutError, AppStartupFailedError, SpaceNotFoundError, AccessDeniedError, ServerFullError, SessionNotFoundError, ServerUnavailableError, BrowserNotSupportedError } from './errors';
9
+ export { ConnectionError, AuthenticationError, TransportError, KeepaliveTimeoutError, AuthRejectedError, MaxRetriesExceededError, ProvisioningTimeoutError, AppStartupFailedError, SpaceNotFoundError, AccessDeniedError, CredentialRejectedError, ServerFullError, SessionNotFoundError, ServerUnavailableError, BrowserNotSupportedError, NoMatchingEndpointTypeError } from './errors';
10
10
  export { checkBrowserSupport, type BrowserSupportResult } from './utils/browser-support';
11
11
  export { Opcode, EntrypointType, UserType, ClientType, ContextType } from '../shared/protocol/src/index.ts';
12
12
  export type { ClientReady, GlobalState, ProtocolMessage, ProtocolMessageHeaders } from '../shared/protocol/src/index.ts';
@@ -18,9 +18,10 @@ export { initializeDebugMode, isDebugModeEnabled } from './utils/debug-mode';
18
18
  export { randomUuid } from './utils/uuid';
19
19
  export { abortSignalTimeout, abortSignalAny } from './utils/abort-signal';
20
20
  export { createPkceChallenge, takePkceVerifier, restorePkceVerifier, isPkceSupported } from './utils/pkce';
21
- export { isEmbedded, startEmbeddedOAuthSignIn, adoptPkceVerifierFromUrl, onEmbeddedOAuthResult, PKCE_URL_PARAM, type EmbeddedOAuthResult } from './utils/embedded-oauth';
21
+ export { isEmbedded, startEmbeddedOAuthSignIn, adoptPkceVerifierFromUrl, onEmbeddedOAuthResult, type EmbeddedOAuthResult } from './utils/embedded-oauth';
22
22
  export { initializeInspectMode, isInspectModeEnabled, enableInspectMode, IKON_INSPECT_MODE_CHANGED_EVENT } from './utils/inspect-mode';
23
- export { getLangParam, getProxyParam, getProxyTierParam, getWebSocketParam, getWebTransportParam, getDebugParam, getServerUrlParam, getConnectParam, getAudioParam, getVideoParam, getWebRtcParam, getInspectParam, getDebugOverlayParam, getAuthSameOriginParam, getRetryParam, setSdkUrlParam, IKON_PARAM_PROXY, IKON_PARAM_WEBSOCKET, IKON_PARAM_WEBTRANSPORT, IKON_PARAM_DEBUG, IKON_PARAM_LANG, IKON_PARAM_SERVER_URL, IKON_PARAM_CONNECT, IKON_PARAM_AUDIO, IKON_PARAM_VIDEO, IKON_PARAM_WEBRTC, IKON_PARAM_INSPECT, IKON_PARAM_DEBUG_OVERLAY, IKON_PARAM_AUTH, IKON_PARAM_RETRY } from './utils/query-params';
23
+ export { getProxyTierParam, getTransportParam, getConnectParam, getSessionParam, getSameOriginParam, getDebugParam, getDebugOverlayParam, getInspectParam, getLangParam, getAudioParam, getVideoParam, getWebRtcParam, getIceTransportPolicyParam, getRetryParam, getSnapshotParam, getSignedOutParam, setSdkUrlParam, IKON_PARAM_PROXY, IKON_PARAM_TRANSPORT, IKON_PARAM_CONNECT, IKON_PARAM_SESSION, IKON_PARAM_SAME_ORIGIN, IKON_PARAM_DEBUG, IKON_PARAM_DEBUG_OVERLAY, IKON_PARAM_INSPECT, IKON_PARAM_LANG, IKON_PARAM_AUDIO, IKON_PARAM_VIDEO, IKON_PARAM_WEBRTC, IKON_PARAM_ICE_TRANSPORT, IKON_PARAM_RETRY, IKON_PARAM_SNAPSHOT, IKON_PARAM_SIGNED_OUT, IKON_PARAM_OAUTH_TOKEN, IKON_PARAM_OAUTH_CODE, IKON_PARAM_OAUTH_PROVIDER, IKON_PARAM_OAUTH_PKCE, type TransportFamily, type PinnedTransport, } from './utils/query-params';
24
+ export type { HttpStreamMode } from './transport/transport';
24
25
  export { getOpcodeName } from './utils/opcode-names';
25
26
  export { initializeLogSink, setSendLogsCallback, getBufferedLogs, takeBufferedLogs, flushLogs, clearLogBuffer, getLogBufferSize } from './utils/log-sink';
26
27
  export type { LogSinkConfig } from './utils/log-sink';
@@ -31,7 +32,7 @@ export { withResultData } from './functions';
31
32
  export type { ValueDescriptor, NormalizedValueDescriptor, PrimitiveValueKind, FunctionParameterDefinition, FunctionDefinition, FunctionHandler, FunctionResultWithData } from './functions';
32
33
  export { loginErrorInterceptor, reprovisionAfterLogin, consumeLoginHandoff, getLoginPromptState, clearLoginPrompt, setLoginPromptRequired, subscribe as subscribeLoginPrompt, consumeLoginPendingCall } from './login';
33
34
  export type { LoginPromptState, LoginPendingCall } from './login';
34
- export { IKON_AUTH_BASE_URL, IKON_AUTH_URL_PROD, IKON_AUTH_URL_DEV, IKON_BACKEND_URL_PROD, IKON_BACKEND_URL_DEV, deriveAuthUrl, deriveCrossOriginAuthUrl, getSameOriginAuthUrl, deriveBackendUrl, deriveBackendType, parseUrlParams, isCloudEnvironment, type UrlParams } from './connection/urls';
35
+ export { IKON_AUTH_BASE_URL, IKON_AUTH_URL_PROD, IKON_AUTH_URL_DEV, IKON_BACKEND_URL_PROD, IKON_BACKEND_URL_DEV, deriveAuthUrl, deriveCrossOriginAuthUrl, getSameOriginAuthUrl, deriveBackendUrl, deriveBackendType, parseUrlParams, isCloudEnvironment, getUrlWithoutSession, type UrlParams } from './connection/urls';
35
36
  export { getOrCreateDeviceId, clearDeviceId, extractUserIdFromToken } from './storage';
36
37
  export { IkonMedia, IkonAudioPlayback, IkonVideoPlayback, VisemeTracker, isSharedArrayBufferSupported, isAudioWorkletSupported, IkonMediaCapture, IkonVideoCapture, IkonAudioCapture, IkonImageCapture, isMobileBrowserLikely } from './media';
37
38
  export type { IkonMediaConfig, IkonAudioPlaybackConfig, IkonVideoPlaybackConfig, IkonVideoCaptureHandle, IkonVideoCaptureRequest, IkonVideoCaptureOptions, VideoCaptureSource, IkonAudioCaptureHandle, IkonAudioCaptureRequest, IkonAudioCaptureOptions, IkonImageCaptureRequest, IkonImageCaptureResult, IkonNativeCameraCaptureRequest, IkonNativeCameraFacing } from './media';