@ikonai/sdk 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/protocol-worker-CW7oSQmQ.js +3 -0
- package/channel/channel-manager.d.ts +12 -0
- package/channel/channel.d.ts +16 -0
- package/client/endpoint-selector.d.ts +27 -0
- package/client/ikon-client-config.d.ts +13 -2
- package/client/ikon-client.d.ts +82 -1
- package/connection/urls.d.ts +13 -9
- package/errors/index.d.ts +27 -0
- package/{ikon-media-DFsofNyM.js → ikon-media-CdIF9gbL.js} +1 -1
- package/index.d.ts +5 -4
- package/index.js +1470 -1023
- package/package.json +1 -1
- package/transport/http-stream-transport.d.ts +107 -0
- package/transport/message-framer.d.ts +36 -0
- package/transport/transport.d.ts +20 -0
- package/transport/web-transport-transport.d.ts +1 -20
- package/utils/embedded-oauth.d.ts +0 -9
- package/utils/log-sender.d.ts +1 -0
- package/utils/query-params.d.ts +85 -49
- package/assets/protocol-worker-CrtCRqQw.js +0 -1
|
@@ -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.
|
package/channel/channel.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
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
|
-
*
|
|
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
|
package/client/ikon-client.d.ts
CHANGED
|
@@ -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
|
/**
|
package/connection/urls.d.ts
CHANGED
|
@@ -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-
|
|
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-
|
|
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-
|
|
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,
|
|
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 {
|
|
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';
|