@ikonai/sdk 1.6.0 → 1.8.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-PNQ9dfGq.js +3 -0
- package/channel/channel-manager.d.ts +1 -0
- package/client/ikon-client-config.d.ts +3 -0
- package/client/ikon-client.d.ts +13 -27
- package/index.d.ts +4 -3
- package/index.js +5871 -2486
- package/media/index.d.ts +2 -0
- package/media/media-permission.d.ts +47 -0
- package/package.json +5 -2
- package/transport/http-stream-transport.d.ts +1 -1
- package/transport/keepalive-watchdog.d.ts +15 -0
- package/transport/web-socket-transport.d.ts +1 -1
- package/transport/web-transport-transport.d.ts +1 -4
- package/utils/boot-signal.d.ts +14 -0
- package/utils/browser-compat.d.ts +17 -0
- package/utils/browser-support.d.ts +15 -10
- package/utils/query-params.d.ts +18 -0
- package/assets/protocol-worker-CW7oSQmQ.js +0 -3
- package/ikon-media-CdIF9gbL.js +0 -3154
package/media/index.d.ts
CHANGED
|
@@ -15,3 +15,5 @@ export type { IkonAudioCaptureHandle, IkonAudioCaptureRequest, IkonAudioCaptureC
|
|
|
15
15
|
export { IkonImageCapture } from './ikon-image-capture';
|
|
16
16
|
export type { IkonImageCaptureRequest, IkonImageCaptureResult, IkonNativeCameraCaptureRequest, IkonNativeCameraFacing } from './ikon-image-capture';
|
|
17
17
|
export { isMobileBrowserLikely } from './device-detection';
|
|
18
|
+
export { queryMediaPermission, requestMediaPermission, watchMediaPermission } from './media-permission';
|
|
19
|
+
export type { MediaPermissionState, MediaPermissionKind } from './media-permission';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Microphone/camera permission state, kept in its own dependency-free module so the
|
|
3
|
+
* eagerly-rendered capture button can read it without statically pulling in the heavy
|
|
4
|
+
* (lazily-loaded) capture pipeline.
|
|
5
|
+
*
|
|
6
|
+
* The reason this exists at all: asking for a permission from inside a press gesture is
|
|
7
|
+
* unusable. The browser's permission dialog steals focus, which the page sees as a
|
|
8
|
+
* pointer release, so the first hold is cancelled while the user is still reading the
|
|
9
|
+
* prompt — and once they answer, nothing was captured and the button looks idle. Every
|
|
10
|
+
* platform that got this right (Discord, Meet, Slack huddles) makes the grant its own
|
|
11
|
+
* explicit step and only then offers the talk gesture.
|
|
12
|
+
*/
|
|
13
|
+
/** What a capture surface is allowed to do right now. */
|
|
14
|
+
export type MediaPermissionState =
|
|
15
|
+
/** Capture can start immediately; no dialog will appear. */
|
|
16
|
+
'granted'
|
|
17
|
+
/** Not asked yet (or the browser will not say) — asking will show the dialog. */
|
|
18
|
+
| 'prompt'
|
|
19
|
+
/** The user said no. Asking again does nothing; only browser/OS settings can undo it. */
|
|
20
|
+
| 'denied'
|
|
21
|
+
/** No device, no `mediaDevices` (insecure context), or not a browser at all. */
|
|
22
|
+
| 'unavailable';
|
|
23
|
+
export type MediaPermissionKind = 'microphone' | 'camera';
|
|
24
|
+
/**
|
|
25
|
+
* Current permission state, without ever showing a dialog.
|
|
26
|
+
*
|
|
27
|
+
* Chromium answers through the Permissions API. Firefox and Safari reject the
|
|
28
|
+
* `microphone`/`camera` descriptor, so we fall back to the device-label heuristic: it can
|
|
29
|
+
* prove `granted` but can never distinguish a fresh `prompt` from a `denied`, and reports
|
|
30
|
+
* `prompt` for both — pressing is then the only way to find out, which is exactly what the
|
|
31
|
+
* button does.
|
|
32
|
+
*/
|
|
33
|
+
export declare function queryMediaPermission(kind: MediaPermissionKind): Promise<MediaPermissionState>;
|
|
34
|
+
/**
|
|
35
|
+
* Asks for the permission and resolves with the answer. Opens a stream and closes it
|
|
36
|
+
* again: the grant is what we are after, not the audio.
|
|
37
|
+
*
|
|
38
|
+
* Must be called from a user gesture — iOS Safari rejects it otherwise, and Chromium
|
|
39
|
+
* ignores a prompt the user never asked for.
|
|
40
|
+
*/
|
|
41
|
+
export declare function requestMediaPermission(kind: MediaPermissionKind): Promise<MediaPermissionState>;
|
|
42
|
+
/**
|
|
43
|
+
* Calls `onChange` whenever the permission state changes — the user answering the dialog,
|
|
44
|
+
* revoking access from the address bar, or plugging a device in or out. Returns the
|
|
45
|
+
* unsubscribe function; call it on teardown.
|
|
46
|
+
*/
|
|
47
|
+
export declare function watchMediaPermission(kind: MediaPermissionKind, onChange: (state: MediaPermissionState) => void): () => void;
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ikonai/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"types": "./index.d.ts",
|
|
7
|
-
"sideEffects":
|
|
7
|
+
"sideEffects": [
|
|
8
|
+
"./index.js",
|
|
9
|
+
"./src/index.ts"
|
|
10
|
+
],
|
|
8
11
|
"exports": {
|
|
9
12
|
".": {
|
|
10
13
|
"import": "./index.js",
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { KeepaliveTimeoutError } from '../errors';
|
|
2
|
+
/**
|
|
3
|
+
* The transport-side dead-link detector, one implementation for every transport: the server
|
|
4
|
+
* promises a keepalive cadence at connect, and a silence longer than the promised watchdog closes
|
|
5
|
+
* the transport so the reconnect ladder can take over.
|
|
6
|
+
*/
|
|
7
|
+
export declare class KeepaliveWatchdog {
|
|
8
|
+
private readonly timeoutMs;
|
|
9
|
+
private readonly what;
|
|
10
|
+
private readonly onTimeout;
|
|
11
|
+
private timeout;
|
|
12
|
+
constructor(timeoutMs: number, what: string, onTimeout: (error: KeepaliveTimeoutError) => void);
|
|
13
|
+
reset(): void;
|
|
14
|
+
clear(): void;
|
|
15
|
+
}
|
|
@@ -5,7 +5,7 @@ import { Transport, TransportConfig } from './transport';
|
|
|
5
5
|
*/
|
|
6
6
|
export declare class WebSocketTransport implements Transport {
|
|
7
7
|
private ws;
|
|
8
|
-
private
|
|
8
|
+
private keepalive;
|
|
9
9
|
private isClosed;
|
|
10
10
|
private keepaliveResponseMessage;
|
|
11
11
|
private firstMessageResolver;
|
|
@@ -19,7 +19,7 @@ export declare class WebTransportTransport implements Transport {
|
|
|
19
19
|
private stream;
|
|
20
20
|
private reader;
|
|
21
21
|
private writer;
|
|
22
|
-
private
|
|
22
|
+
private keepalive;
|
|
23
23
|
private readLoopActive;
|
|
24
24
|
private isClosed;
|
|
25
25
|
private readonly framer;
|
|
@@ -55,9 +55,6 @@ export declare class WebTransportTransport implements Transport {
|
|
|
55
55
|
* Reset the keepalive timeout.
|
|
56
56
|
*/
|
|
57
57
|
private resetKeepaliveTimeout;
|
|
58
|
-
/**
|
|
59
|
-
* Clear the keepalive timeout.
|
|
60
|
-
*/
|
|
61
58
|
private clearKeepaliveTimeout;
|
|
62
59
|
/**
|
|
63
60
|
* Clean up resources.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tells the app shell's inline boot watchdog that the bundle is running.
|
|
3
|
+
*
|
|
4
|
+
* The watchdog in `index.html` has to tell a bundle that never arrived from a page that is simply
|
|
5
|
+
* still blank — a sign-in renewal and a slow connection both look identical to a 404 from the
|
|
6
|
+
* outside — and an empty `#root` says nothing either way. This flag is one half of that answer; the
|
|
7
|
+
* module element's own `load` event is the other, and either alone is enough.
|
|
8
|
+
*
|
|
9
|
+
* It lives in the SDK rather than in `index.html` because an app's `index.html` is written once at
|
|
10
|
+
* scaffold time and never rewritten, so the shell's half reaches new apps only, while this one
|
|
11
|
+
* reaches every app that takes an SDK update. Set before any app code runs, for the same reason the
|
|
12
|
+
* browser fallbacks are.
|
|
13
|
+
*/
|
|
14
|
+
export declare function signalBundleRunning(): void;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fallbacks for methods that a browser old enough to still be supported may not have.
|
|
3
|
+
*
|
|
4
|
+
* Every entry is a *runtime* API rather than syntax, so no build target can down-level it: the call
|
|
5
|
+
* simply throws, mid-render, where the app cannot catch it — a blank screen rather than an error.
|
|
6
|
+
* Syntax is the other half of the problem and is not solved here, because a browser that cannot
|
|
7
|
+
* parse the bundle never reaches this module; {@link checkBrowserSupport} and the app shell's
|
|
8
|
+
* inline gate cover that case.
|
|
9
|
+
*
|
|
10
|
+
* The SDK applies these when it is first evaluated, which is before any app code runs. It lives in
|
|
11
|
+
* the SDK rather than in the app shell's `index.html` because an app's `index.html` is written once
|
|
12
|
+
* at scaffold time and never rewritten, so a fallback added there reaches new apps only.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Apply every fallback the current browser needs. Idempotent, and a no-op on a current browser.
|
|
16
|
+
*/
|
|
17
|
+
export declare function applyBrowserCompat(): void;
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Runtime feature detection for the SDK's hard requirements.
|
|
3
3
|
*
|
|
4
|
-
* These are the features the SDK genuinely cannot run without
|
|
5
|
-
* the connect path needs `fetch`, the Teleport
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* These are the features the SDK genuinely cannot run without and cannot stand in for: the
|
|
5
|
+
* transport needs `WebSocket`, the connect path needs `fetch`, and the Teleport codec needs `BigInt`
|
|
6
|
+
* for every 64-bit field. All of them shipped by Chromium 67 / Firefox 68 / Safari 14 (2018-20), so
|
|
7
|
+
* a missing one means a genuinely outdated browser (e.g. a legacy smart-TV) — this never trips on
|
|
8
|
+
* a current browser.
|
|
9
|
+
*
|
|
10
|
+
* `BigInt` stands in for the `DataView` 64-bit accessors the codec calls beside it: they shipped
|
|
11
|
+
* together in every engine, so one check covers both and a second would only be noise.
|
|
9
12
|
*
|
|
10
13
|
* It deliberately does NOT check features the SDK already feature-detects and falls back for
|
|
11
|
-
* (`crypto.randomUUID`, `AbortSignal.timeout`),
|
|
14
|
+
* (`crypto.randomUUID`, `AbortSignal.timeout`), polyfills in `browser-compat.ts`
|
|
15
|
+
* (`Promise.allSettled` and `globalThis` among them), gates server-side (`DecompressionStream` via
|
|
12
16
|
* `SupportsCompression`), or loads lazily (`WebAssembly`, only when audio starts).
|
|
13
17
|
*
|
|
14
|
-
* NOTE: `BigInt`
|
|
15
|
-
* (`
|
|
16
|
-
*
|
|
17
|
-
* that
|
|
18
|
+
* NOTE: `BigInt` is a runtime requirement, not a parse-time one — the generated protocol modules
|
|
19
|
+
* call `BigInt(0)` rather than writing `0n`, so a BigInt-less browser reaches this check instead
|
|
20
|
+
* of failing to parse the bundle before it. The app shell's inline gate tests this same list
|
|
21
|
+
* before the module loads, so that a browser missing one of them is told so rather than left
|
|
22
|
+
* looking at whatever the module managed to do before it threw. Keep the two lists identical.
|
|
18
23
|
*/
|
|
19
24
|
export interface BrowserSupportResult {
|
|
20
25
|
readonly supported: boolean;
|
package/utils/query-params.d.ts
CHANGED
|
@@ -28,6 +28,9 @@ import { HttpStreamMode } from '../transport/transport';
|
|
|
28
28
|
* - ikon-snapshot Connect as a build-time snapshot client; sets Context.IsSnapshot
|
|
29
29
|
* - ikon-signed-out The user signed out; suppresses auto-login for this load
|
|
30
30
|
*
|
|
31
|
+
* Read by the app shell's index.html rather than by the SDK, and listed so the name stays taken:
|
|
32
|
+
* - ikon-logs Mirror the console onto the screen, for devices with no developer tools
|
|
33
|
+
*
|
|
31
34
|
* OAuth callback parameters, underscore form only. The auth backend sets these on its redirect
|
|
32
35
|
* (backend/libs/auth/user/src/lib/redirect.service.ts), so the names are a wire contract:
|
|
33
36
|
* - ikon_token Session token from a completed OAuth round-trip
|
|
@@ -99,6 +102,21 @@ export declare function getLangParam(): string | null;
|
|
|
99
102
|
* Returns null when the parameter is absent, so a caller can fall back.
|
|
100
103
|
*/
|
|
101
104
|
export declare function getConnectParam(): string | null;
|
|
105
|
+
declare global {
|
|
106
|
+
interface Window {
|
|
107
|
+
/** Set by a launcher's init script before any page script runs; see getResumeHandoff. */
|
|
108
|
+
__IKON_RESUME__?: string;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* An AuthResponse frame handed to this page by the client that already holds the session — a
|
|
113
|
+
* headless driver that launched this browser. Present, the page opens its transport from that
|
|
114
|
+
* response instead of authenticating, and so joins that client's session. The value is the
|
|
115
|
+
* frame's bytes, base64url (the C# SDK's AuthResponseHandoff.Encode), placed on
|
|
116
|
+
* `window.__IKON_RESUME__` by an init script rather than the URL: a frame is kilobytes, and a
|
|
117
|
+
* query that long rides along as the Referer of every module and fetch and gets them refused.
|
|
118
|
+
*/
|
|
119
|
+
export declare function getResumeHandoff(): Uint8Array | null;
|
|
102
120
|
export declare function getAudioParam(): boolean | null;
|
|
103
121
|
export declare function getVideoParam(): boolean | null;
|
|
104
122
|
export declare function getWebRtcParam(): boolean | null;
|
|
@@ -1,3 +0,0 @@
|
|
|
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}});
|