@ikonai/sdk 0.0.11 → 0.0.13

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.
Files changed (35) hide show
  1. package/assets/audio-capture-worker-DbFwKRTJ.js +14727 -0
  2. package/assets/audio-worker-BFOOU5sk.js +14916 -0
  3. package/assets/index-CvFH-Dkf.js +650 -0
  4. package/assets/protocol-worker-DIwctOUY.js +15181 -0
  5. package/assets/video-capture-worker-CJhKrZYf.js +14631 -0
  6. package/assets/video-worker-BhoZnZ1o.js +14659 -0
  7. package/channel/channel-manager.d.ts +14 -4
  8. package/client/ikon-client-config.d.ts +94 -2
  9. package/client/ikon-client.d.ts +104 -4
  10. package/connection/urls.d.ts +13 -0
  11. package/functions/function-registry.d.ts +1 -1
  12. package/functions/index.d.ts +2 -1
  13. package/functions/media-capture-functions.d.ts +9 -0
  14. package/functions/types.d.ts +5 -0
  15. package/index.d.ts +8 -4
  16. package/index.js +11394 -8981
  17. package/media/capabilities.d.ts +13 -0
  18. package/media/ikon-audio-capture.d.ts +34 -0
  19. package/media/ikon-audio-playback.d.ts +157 -0
  20. package/media/ikon-image-capture.d.ts +24 -0
  21. package/media/ikon-media-capture.d.ts +11 -0
  22. package/media/ikon-media.d.ts +27 -0
  23. package/media/ikon-video-capture.d.ts +33 -0
  24. package/media/ikon-video-playback.d.ts +70 -0
  25. package/media/index.d.ts +14 -0
  26. package/media/ring-buffer.d.ts +21 -0
  27. package/package.json +1 -1
  28. package/utils/deferred.d.ts +6 -0
  29. package/utils/opcode-names.d.ts +1 -0
  30. package/utils/user-gesture.d.ts +7 -0
  31. package/worker/audio-capture-worker.d.ts +1 -0
  32. package/worker/audio-worker.d.ts +1 -0
  33. package/worker/protocol-worker.d.ts +1 -0
  34. package/worker/video-capture-worker.d.ts +10 -0
  35. package/worker/video-worker.d.ts +1 -0
@@ -27,7 +27,17 @@ export interface ChannelManagerConfig {
27
27
  /**
28
28
  * Endpoint selector for ordering types.
29
29
  */
30
- endpointSelector: EndpointSelector;
30
+ endpointSelector?: EndpointSelector;
31
+ /**
32
+ * Ordered list of endpoint types to try.
33
+ * Useful for worker environments where localStorage might be unavailable.
34
+ */
35
+ orderedEndpointTypes?: EntrypointType[];
36
+ /**
37
+ * Called when a working endpoint type is discovered.
38
+ * Typically used by the host to persist endpoint preference.
39
+ */
40
+ onRememberWorkingType?: (type: EntrypointType) => void;
31
41
  /**
32
42
  * Callback when a protocol message is received from any channel.
33
43
  */
@@ -47,7 +57,7 @@ export interface ChannelManagerConfig {
47
57
  * Features:
48
58
  * - Groups entrypoints by type
49
59
  * - Tries types in order (WT → WS → WTProxy → WSProxy for prod)
50
- * - Connects core channel first, then others in parallel
60
+ * - Connects all channels in parallel
51
61
  * - Handles reconnection with type fallback
52
62
  * - Routes messages to/from appropriate channels
53
63
  */
@@ -88,11 +98,11 @@ export declare class ChannelManager {
88
98
  sendToAll(message: ProtocolMessage): void;
89
99
  /**
90
100
  * Internal connect implementation.
101
+ * @param isReconnect - If true, don't set offline state on failure (let attemptReconnect handle it)
91
102
  */
92
103
  private connectInternal;
93
104
  /**
94
- * Connect all channels for a given endpoint type.
95
- * Core channel connects first, then others in parallel.
105
+ * Connect all channels for a given endpoint type in parallel.
96
106
  */
97
107
  private connectAllChannels;
98
108
  /**
@@ -1,6 +1,8 @@
1
1
  import { ProtocolMessage } from '../../../../shared/generated/src/index.ts';
2
2
  import { BackendType } from '../connection/urls';
3
3
  import { ConnectionState } from './connection-state';
4
+ import { IkonAudioOutputConfig, IkonAudioPlaybackConfig } from '../media/ikon-audio-playback';
5
+ import { IkonVideoPlaybackConfig } from '../media/ikon-video-playback';
4
6
  export type { BackendType };
5
7
  /**
6
8
  * Common connection options shared across all modes.
@@ -144,6 +146,21 @@ export interface SessionTokenConfig extends CloudConnectionConfig {
144
146
  */
145
147
  backendType?: BackendType;
146
148
  }
149
+ /**
150
+ * Debug configuration for the SDK.
151
+ */
152
+ export interface DebugConfig {
153
+ /**
154
+ * Log sent protocol messages.
155
+ * Format: "Sent {OPCODE_NAME} {senderId} -> {targets}"
156
+ */
157
+ logSentMessages?: boolean;
158
+ /**
159
+ * Log received protocol messages.
160
+ * Format: "Received {senderId} -> {OPCODE_NAME}"
161
+ */
162
+ logReceivedMessages?: boolean;
163
+ }
147
164
  /**
148
165
  * Timeout configuration for the SDK.
149
166
  */
@@ -199,6 +216,81 @@ export interface IkonClientConfig {
199
216
  * Timeout configuration.
200
217
  */
201
218
  timeouts?: TimeoutConfig;
219
+ /**
220
+ * Debug configuration.
221
+ */
222
+ debug?: DebugConfig;
223
+ /**
224
+ * Threading and worker configuration.
225
+ */
226
+ threading?: {
227
+ /**
228
+ * Move protocol send/receive to a WebWorker when possible.
229
+ * - 'auto': try to use a worker and fall back to main thread on failure
230
+ * - 'disabled': always use main thread transports
231
+ */
232
+ protocolWorker?: 'auto' | 'disabled';
233
+ };
234
+ /**
235
+ * Media (audio/video) playback configuration.
236
+ *
237
+ * The SDK treats protocol messages as the canonical representation of streams.
238
+ * This section controls whether the SDK should create and prepare media pipelines
239
+ * (workers, decoders, AudioWorklet) to reduce time-to-first-audio/video.
240
+ */
241
+ media?: {
242
+ /**
243
+ * Audio playback pipeline.
244
+ */
245
+ audio?: {
246
+ /**
247
+ * When enabled, the SDK prepares the audio pipeline and starts decoding as soon as possible.
248
+ *
249
+ * Audio output still depends on browser autoplay policies; the app must ensure a user gesture
250
+ * has occurred before resuming the AudioContext. The SDK surfaces this need via `onAudioUnlockRequired`.
251
+ */
252
+ enabled?: boolean;
253
+ /**
254
+ * Callback fired when audio playback requires a user gesture (autoplay restriction).
255
+ */
256
+ onAudioUnlockRequired?: () => void;
257
+ /**
258
+ * Output format for mixing and rendering.
259
+ */
260
+ output?: IkonAudioOutputConfig;
261
+ /**
262
+ * Threading and capability preferences for audio.
263
+ */
264
+ threading?: IkonAudioPlaybackConfig['threading'];
265
+ };
266
+ /**
267
+ * Video playback pipeline.
268
+ *
269
+ * Video rendering requires an explicit surface (canvas) provided by the app.
270
+ * The SDK can still prepare worker/decoder plumbing to reduce time-to-first-frame.
271
+ */
272
+ video?: {
273
+ enabled?: boolean;
274
+ threading?: IkonVideoPlaybackConfig['threading'];
275
+ };
276
+ };
277
+ /**
278
+ * Media capture configuration (microphone/camera/screen/image).
279
+ *
280
+ * The SDK does not render any UI. When browser policies require a user gesture
281
+ * to start capture, the SDK notifies the host app via `onUserGestureRequired`.
282
+ *
283
+ * The app should show its own overlay and call `request.resume()` directly
284
+ * from a user gesture handler (e.g. button click) so the browser treats the
285
+ * subsequent getUserMedia/getDisplayMedia call as user-initiated.
286
+ */
287
+ mediaCapture?: {
288
+ onUserGestureRequired?: (request: {
289
+ kind: 'microphone' | 'camera' | 'screen' | 'image';
290
+ resume: () => void;
291
+ cancel?: () => void;
292
+ }) => void;
293
+ };
202
294
  /**
203
295
  * Callback when a protocol message is received.
204
296
  * The SDK handles keepalive internally; other messages are passed to this callback.
@@ -220,12 +312,12 @@ export interface IkonClientConfig {
220
312
  */
221
313
  onVisibilityChange?: (isVisible: boolean) => void;
222
314
  /**
223
- * Called when connected to the server (including reconnects).
315
+ * Called when all endpoints are connected and GlobalState is received (including reconnects).
224
316
  * Perform any initialization here. After this callback completes,
225
317
  * the SDK sends ClientReady to the server.
226
318
  * Can be async (return a Promise).
227
319
  */
228
- onReady?: () => void | Promise<void>;
320
+ onJoined?: () => void | Promise<void>;
229
321
  /**
230
322
  * Disable auto-registration of browser convenience functions.
231
323
  * By default, functions like getTheme, setTheme, getLocation, etc. are
@@ -1,11 +1,52 @@
1
1
  import { GlobalState, ProtocolMessage } from '../../../../shared/generated/src/index.ts';
2
2
  import { FunctionRegistry } from '../functions/function-registry';
3
+ import { IkonMedia } from '../media/ikon-media';
4
+ import { IkonMediaCapture } from '../media/ikon-media-capture';
5
+ import { UserGestureRequest } from '../utils/user-gesture';
3
6
  import { ConnectionState } from './connection-state';
4
7
  import { IkonClientConfig } from './ikon-client-config';
5
8
  /**
6
9
  * Protocol message handler callback type for subscribers.
7
10
  */
8
11
  export type ProtocolMessageHandler = (message: ProtocolMessage) => void;
12
+ /**
13
+ * A MessagePort that receives raw protocol messages as transferred ArrayBuffers.
14
+ *
15
+ * This is intended for advanced integrations where decoding and processing should
16
+ * happen off the UI thread (e.g. media decode workers). The messages are still the
17
+ * canonical Teleport protocol payloads.
18
+ */
19
+ export interface ProtocolMessagePort {
20
+ port: MessagePort;
21
+ close: () => void;
22
+ }
23
+ /**
24
+ * A MessagePort that accepts outbound protocol messages as transferred ArrayBuffers.
25
+ *
26
+ * This enables high-throughput producers (e.g. media capture encode workers) to send
27
+ * protocol messages without bouncing through the main thread.
28
+ */
29
+ export interface ProtocolSendPort {
30
+ port: MessagePort;
31
+ close: () => void;
32
+ }
33
+ export interface ProtocolMessageSubscriptionOptions {
34
+ /**
35
+ * Bitmask of opcode groups to receive for this subscriber.
36
+ *
37
+ * This exists to keep protocol messages first-class while still allowing
38
+ * high-throughput clients to reduce work (and message copies) when only a
39
+ * subset of the protocol is relevant to the current app state.
40
+ */
41
+ opcodeGroupsMask?: number;
42
+ /**
43
+ * Optional explicit opcode list for this subscriber.
44
+ *
45
+ * When provided, the SDK falls back to forwarding all messages from the protocol worker,
46
+ * because the worker only filters by opcode group to keep routing cheap.
47
+ */
48
+ opcodes?: number[];
49
+ }
9
50
  /**
10
51
  * State handler callback type for state subscribers.
11
52
  */
@@ -39,6 +80,8 @@ export type StateHandler = (state: ConnectionState) => void;
39
80
  */
40
81
  export declare class IkonClient {
41
82
  private channelManager;
83
+ private protocolWorker;
84
+ private workerManagerState;
42
85
  private authResponse;
43
86
  private currentState;
44
87
  private slowConnectionTimer;
@@ -54,10 +97,32 @@ export declare class IkonClient {
54
97
  private boundPageHide;
55
98
  private boundVisibilityChange;
56
99
  private _globalState;
57
- private _initialGlobalStateReceived;
100
+ private _globalStateReceived;
101
+ private _channelsConnected;
102
+ private _joinedHandled;
58
103
  private readonly _functionRegistry;
59
104
  private unregisterBrowserFunctions;
105
+ private unregisterMediaCaptureFunctions;
106
+ private nextProtocolPortId;
107
+ private nextProtocolSendPortId;
108
+ private readonly _media;
109
+ private _mediaCapture;
110
+ /**
111
+ * Optional SDK-provided media pipelines (audio/video).
112
+ *
113
+ * These are only created when `IkonClientConfig.media` is provided. Keeping media
114
+ * optional avoids pulling in extra worker graphs and Web APIs for apps that only
115
+ * need protocol + UI streaming.
116
+ */
117
+ get media(): IkonMedia | null;
118
+ /**
119
+ * Optional SDK-provided media capture pipelines (audio/video/image).
120
+ *
121
+ * These are only available in browser environments.
122
+ */
123
+ get mediaCapture(): IkonMediaCapture | null;
60
124
  constructor(config: IkonClientConfig);
125
+ requestUserGesture(request: UserGestureRequest): void;
61
126
  private _lastError;
62
127
  /**
63
128
  * Get the error that caused 'offlineError' state, if any.
@@ -98,11 +163,37 @@ export declare class IkonClient {
98
163
  * Routes to appropriate channel based on the message's opcode group.
99
164
  */
100
165
  sendProtocolMessage(message: ProtocolMessage): void;
166
+ /**
167
+ * Create a MessagePort that receives raw protocol message buffers.
168
+ *
169
+ * This is primarily used to build high-throughput pipelines (audio/video/UI)
170
+ * where the heavy work is done in dedicated workers, while keeping the protocol
171
+ * messages themselves as the source of truth.
172
+ *
173
+ * If the client is using a protocol worker, the port is attached directly to it.
174
+ * Otherwise, the SDK forwards matching messages from the main thread as a fallback.
175
+ */
176
+ createProtocolMessagePort(options: {
177
+ opcodeGroupsMask: number;
178
+ }): ProtocolMessagePort | null;
179
+ /**
180
+ * Create a MessagePort that can send raw protocol messages as transferred ArrayBuffers.
181
+ *
182
+ * This is primarily used by worker-based encoders that need to stream large amounts of
183
+ * data (audio/video frames) while keeping protocol messages as the canonical payload.
184
+ *
185
+ * When the SDK is using a protocol worker, the port is attached directly to it.
186
+ * Otherwise, the SDK listens on the port on the main thread and forwards messages to
187
+ * the active channel manager.
188
+ */
189
+ createProtocolSendPort(options: {
190
+ opcodeGroupsMask: number;
191
+ }): ProtocolSendPort | null;
101
192
  /**
102
193
  * Subscribe to protocol messages.
103
194
  * Returns an unsubscribe function.
104
195
  */
105
- subscribeToProtocolMessages(handler: ProtocolMessageHandler): () => void;
196
+ subscribeToProtocolMessages(handler: ProtocolMessageHandler, options?: ProtocolMessageSubscriptionOptions): () => void;
106
197
  /**
107
198
  * Subscribe to connection state changes.
108
199
  * Handler is called immediately with current state, then on every change.
@@ -134,6 +225,11 @@ export declare class IkonClient {
134
225
  * Use this for unrecoverable SDK internal errors.
135
226
  */
136
227
  private setErrorState;
228
+ private connectProtocol;
229
+ private connectProtocolOnMainThread;
230
+ private disconnectProtocol;
231
+ private computeOrderedEndpointTypes;
232
+ private updateWorkerInterestMask;
137
233
  /**
138
234
  * Clear all timers.
139
235
  */
@@ -167,8 +263,12 @@ export declare class IkonClient {
167
263
  */
168
264
  private checkConnectionHealth;
169
265
  /**
170
- * Handle connection ready - attach function registry, call user's onReady callback, then send ClientReady.
266
+ * Try to handle joined state - only proceeds if both channels are connected and GlobalState is received.
267
+ */
268
+ private tryHandleJoined;
269
+ /**
270
+ * Handle joined state - attach function registry, call user's onJoined callback, then send ClientReady.
171
271
  * Called on every connect (including reconnects).
172
272
  */
173
- private handleReady;
273
+ private handleJoined;
174
274
  }
@@ -7,6 +7,11 @@
7
7
  export type BackendType = 'production' | 'development';
8
8
  export declare const IKON_BACKEND_URL_PROD = "https://api.prod.ikon.live";
9
9
  export declare const IKON_BACKEND_URL_DEV = "https://api.dev.ikon.live";
10
+ export declare const IKON_AUTH_URL_PROD = "https://auth.ikonai.com";
11
+ export declare const IKON_AUTH_URL_DEV = "https://auth.dev.ikonai.com";
12
+ /**
13
+ * @deprecated Use deriveAuthUrl() instead
14
+ */
10
15
  export declare const IKON_AUTH_BASE_URL = "https://auth.ikonai.com";
11
16
  /**
12
17
  * Get backend URL from BackendType.
@@ -25,6 +30,14 @@ export declare function deriveBackendUrl(): string;
25
30
  * - Otherwise → 'production'
26
31
  */
27
32
  export declare function deriveBackendType(): BackendType;
33
+ /**
34
+ * Derive auth service URL from environment or window.location.hostname.
35
+ * - VITE_IKON_AUTH_URL env var takes precedence (for local development)
36
+ * - localhost/127.0.0.1 → http://localhost:3400
37
+ * - hostname contains '.dev.' → IKON_AUTH_URL_DEV
38
+ * - Otherwise → IKON_AUTH_URL_PROD
39
+ */
40
+ export declare function deriveAuthUrl(): string;
28
41
  /**
29
42
  * Parse URL query parameters.
30
43
  */
@@ -44,7 +44,7 @@ export declare class FunctionRegistry {
44
44
  */
45
45
  handleProtocolMessage(message: ProtocolMessage, opcode: number): boolean;
46
46
  /**
47
- * Send registrations for all functions.
47
+ * Send registrations for all functions as a batch.
48
48
  * Called when connection is established or re-established.
49
49
  */
50
50
  private sendAllRegistrations;
@@ -1,3 +1,4 @@
1
- export type { ValueDescriptor, NormalizedValueDescriptor, PrimitiveValueKind, FunctionParameterDefinition, FunctionDefinition, FunctionHandler, } from './types';
1
+ export type { ValueDescriptor, NormalizedValueDescriptor, PrimitiveValueKind, FunctionParameterDefinition, FunctionDefinition, FunctionHandler, FunctionResultWithData, } from './types';
2
+ export { withResultData } from './types';
2
3
  export { FunctionRegistry, type FunctionRegistryConfig } from './function-registry';
3
4
  export { registerBrowserFunctions, isBrowserEnvironment } from './browser-functions';
@@ -0,0 +1,9 @@
1
+ import { IkonClient } from '../client/ikon-client';
2
+ import { FunctionRegistry } from './function-registry';
3
+ export declare const MediaCaptureFunctionNames: {
4
+ readonly StartVideoCapture: "ikon.client.startVideoCapture";
5
+ readonly StartAudioCapture: "ikon.client.startAudioCapture";
6
+ readonly StopCapture: "ikon.client.stopCapture";
7
+ readonly CaptureImage: "ikon.client.captureImage";
8
+ };
9
+ export declare function registerMediaCaptureFunctions(registry: FunctionRegistry, client: IkonClient): () => void;
@@ -45,6 +45,11 @@ export interface FunctionDefinition {
45
45
  parameters?: FunctionParameterDefinition[];
46
46
  }
47
47
  export type FunctionHandler = (...parameters: unknown[]) => unknown | Promise<unknown>;
48
+ export interface FunctionResultWithData<T = unknown> {
49
+ value: T;
50
+ data: Uint8Array;
51
+ }
52
+ export declare function withResultData<T>(value: T, data: Uint8Array): FunctionResultWithData<T>;
48
53
  export interface NormalizedFunctionParameter {
49
54
  name: string;
50
55
  descriptor: NormalizedValueDescriptor;
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { IkonClient, type ProtocolMessageHandler, type StateHandler } from './client/ikon-client';
2
- export type { IkonClientConfig, LocalConfig, ApiKeyConfig, SessionTokenConfig, CloudConnectionConfig, CommonConnectionConfig, TimeoutConfig, BackendType } from './client/ikon-client-config';
1
+ export { IkonClient, type ProtocolMessageHandler, type StateHandler, type ProtocolMessageSubscriptionOptions, type ProtocolMessagePort, type ProtocolSendPort, } from './client/ikon-client';
2
+ export type { IkonClientConfig, LocalConfig, ApiKeyConfig, SessionTokenConfig, CloudConnectionConfig, CommonConnectionConfig, TimeoutConfig, DebugConfig, BackendType } from './client/ikon-client-config';
3
3
  export type { ConnectionState } from './client/connection-state';
4
4
  export { isConnecting, isConnected, isOffline, isError } from './client/connection-state';
5
5
  export { ChannelManager, type ChannelManagerConfig, type ChannelManagerState } from './channel/channel-manager';
@@ -12,9 +12,13 @@ export { teleportReadOpcode as readOpcode, teleportReadOpcodeGroup as readOpcode
12
12
  export { isWebTransportSupported } from './transport/web-transport-transport';
13
13
  export { setLogLevel, setLogSink, getLogLevel, getLogSink, createLogger, LogLevel } from './utils/logger';
14
14
  export type { LogEntry, LogSink, Logger } from './utils/logger';
15
+ export { getOpcodeName } from './utils/opcode-names';
15
16
  export { initializeLogSink, setSendLogsCallback, getBufferedLogs, takeBufferedLogs, flushLogs, clearLogBuffer, getLogBufferSize } from './utils/logSink';
16
17
  export type { LogSinkConfig } from './utils/logSink';
17
18
  export { FunctionRegistry, registerBrowserFunctions, isBrowserEnvironment, type FunctionRegistryConfig } from './functions';
18
- export type { ValueDescriptor, NormalizedValueDescriptor, PrimitiveValueKind, FunctionParameterDefinition, FunctionDefinition, FunctionHandler } from './functions';
19
- export { IKON_AUTH_BASE_URL, IKON_BACKEND_URL_PROD, IKON_BACKEND_URL_DEV, deriveBackendUrl, deriveBackendType, parseUrlParams, isCloudEnvironment, type UrlParams } from './connection/urls';
19
+ export { withResultData } from './functions';
20
+ export type { ValueDescriptor, NormalizedValueDescriptor, PrimitiveValueKind, FunctionParameterDefinition, FunctionDefinition, FunctionHandler, FunctionResultWithData, } from './functions';
21
+ export { IKON_AUTH_BASE_URL, IKON_AUTH_URL_PROD, IKON_AUTH_URL_DEV, IKON_BACKEND_URL_PROD, IKON_BACKEND_URL_DEV, deriveAuthUrl, deriveBackendUrl, deriveBackendType, parseUrlParams, isCloudEnvironment, type UrlParams } from './connection/urls';
20
22
  export { getOrCreateDeviceId, clearDeviceId, extractUserIdFromToken } from './storage';
23
+ export { IkonMedia, IkonAudioPlayback, IkonVideoPlayback, isSharedArrayBufferSupported, isAudioWorkletSupported, IkonMediaCapture, IkonVideoCapture, IkonAudioCapture, IkonImageCapture, } from './media';
24
+ export type { IkonMediaConfig, IkonAudioPlaybackConfig, IkonAudioOutputConfig, IkonVideoPlaybackConfig, IkonVideoCaptureHandle, IkonVideoCaptureRequest, VideoCaptureSource, IkonAudioCaptureHandle, IkonAudioCaptureRequest, IkonImageCaptureRequest, IkonImageCaptureResult, } from './media';