@cuekit-ai/react 1.3.4 → 1.5.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/dist/index.js CHANGED
@@ -112,15 +112,24 @@ var init_intent_store = __esm({
112
112
 
113
113
  // src/core/navigation.ts
114
114
  function setNavigationHandler(handler) {
115
+ console.log("\u{1F9ED} setNavigationHandler called with:", !!handler);
115
116
  navigationHandler = handler;
116
117
  }
117
118
  function navigate(path2, params) {
118
119
  const safeParams = params || {};
119
120
  const absolutePath = path2.startsWith("/") ? path2 : `/${path2}`;
121
+ console.log("\u{1F9ED} navigate() called with:", {
122
+ path: path2,
123
+ absolutePath,
124
+ safeParams,
125
+ hasNavigationHandler: !!navigationHandler
126
+ });
120
127
  if (navigationHandler) {
121
128
  try {
129
+ console.log("\u{1F9ED} Using navigationHandler:", absolutePath, safeParams);
122
130
  navigationHandler(absolutePath, safeParams);
123
131
  } catch (error) {
132
+ console.error("\u{1F9ED} NavigationHandler error:", error);
124
133
  }
125
134
  return;
126
135
  }
@@ -135,13 +144,22 @@ function navigate(path2, params) {
135
144
  navigation.push(fullPath);
136
145
  } else {
137
146
  if (typeof window !== "undefined") {
138
- window.location.href = fullPath;
147
+ if (window.location.hash && window.location.hash.startsWith("#")) {
148
+ window.location.hash = fullPath;
149
+ } else {
150
+ window.location.href = fullPath;
151
+ }
139
152
  }
140
153
  }
141
154
  }
142
155
  function getCurrentScreenName() {
143
156
  try {
144
157
  const path2 = getCurrentPath();
158
+ const pathParams = getCurrentPathParams();
159
+ if (path2 && Object.keys(pathParams).length > 0) {
160
+ const paramString = Object.entries(pathParams).map(([key, value]) => `${key}=${value}`).join(",");
161
+ return `${path2}?${paramString}`;
162
+ }
145
163
  return path2 || "UnknownScreen";
146
164
  } catch (e3) {
147
165
  return "UnknownScreen";
@@ -163,6 +181,45 @@ function getCurrentRouteParams() {
163
181
  return {};
164
182
  }
165
183
  }
184
+ function getCurrentPathParams() {
185
+ try {
186
+ const currentPath = getCurrentPath();
187
+ const params = {};
188
+ const numericIdMatch = currentPath.match(/\/(\d+)(?:\/|$)/);
189
+ if (numericIdMatch) {
190
+ params.id = numericIdMatch[1];
191
+ }
192
+ const uuidMatch = currentPath.match(
193
+ /\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:\/|$)/i
194
+ );
195
+ if (uuidMatch) {
196
+ params.uuid = uuidMatch[1];
197
+ }
198
+ const slugMatch = currentPath.match(/\/([a-z0-9-]+)(?:\/|$)/i);
199
+ if (slugMatch && !numericIdMatch && !uuidMatch) {
200
+ params.slug = slugMatch[1];
201
+ }
202
+ return params;
203
+ } catch (e3) {
204
+ return {};
205
+ }
206
+ }
207
+ function resolveRoutePath(routePath, params) {
208
+ try {
209
+ let resolvedPath = routePath;
210
+ Object.entries(params).forEach(([key, value]) => {
211
+ const placeholder = `:${key}`;
212
+ if (resolvedPath.includes(placeholder)) {
213
+ resolvedPath = resolvedPath.replace(placeholder, value);
214
+ }
215
+ });
216
+ resolvedPath = resolvedPath.replace(/:\w+/g, "");
217
+ resolvedPath = resolvedPath.replace(/\/+/g, "/");
218
+ return resolvedPath;
219
+ } catch (e3) {
220
+ return routePath;
221
+ }
222
+ }
166
223
  function onStateChange() {
167
224
  const routeName = getCurrentScreenName();
168
225
  const params = getCurrentRouteParams();
@@ -202,16 +259,26 @@ var init_navigation = __esm({
202
259
  navigationHandler = null;
203
260
  getCurrentPath = () => {
204
261
  if (typeof window === "undefined") return "";
262
+ if (window.location.hash && window.location.hash.startsWith("#")) {
263
+ const hashPath = window.location.hash.substring(1);
264
+ return hashPath.split("?")[0];
265
+ }
205
266
  return window.location.pathname;
206
267
  };
207
268
  getSearchParams = () => {
208
269
  if (typeof window === "undefined") return new URLSearchParams();
270
+ if (window.location.hash && window.location.hash.includes("?")) {
271
+ const queryString = window.location.hash.split("?")[1];
272
+ return new URLSearchParams(queryString);
273
+ }
209
274
  return new URLSearchParams(window.location.search);
210
275
  };
211
276
  safeNavigate = (name2, params = {}) => {
277
+ console.log("\u{1F9ED} safeNavigate called with:", { name: name2, params });
212
278
  if (name2) {
213
279
  navigate(name2, params);
214
280
  } else {
281
+ console.log("\u{1F9ED} safeNavigate: no name provided, skipping navigation");
215
282
  }
216
283
  };
217
284
  handleNavigationAndClick = (routeName, elementHash) => {
@@ -5296,7 +5363,7 @@ function supportsAV1() {
5296
5363
  if (!("getCapabilities" in RTCRtpSender)) {
5297
5364
  return false;
5298
5365
  }
5299
- if (isSafari()) {
5366
+ if (isSafari() || isFireFox()) {
5300
5367
  return false;
5301
5368
  }
5302
5369
  const capabilities = RTCRtpSender.getCapabilities("video");
@@ -5393,9 +5460,9 @@ function isE2EESimulcastSupported() {
5393
5460
  if (browser) {
5394
5461
  if (browser.name !== "Safari" && browser.os !== "iOS") {
5395
5462
  return true;
5396
- } else if (browser.os === "iOS" && browser.osVersion && compareVersions(supportedSafariVersion, browser.osVersion) >= 0) {
5463
+ } else if (browser.os === "iOS" && browser.osVersion && compareVersions(browser.osVersion, supportedSafariVersion) >= 0) {
5397
5464
  return true;
5398
- } else if (browser.name === "Safari" && compareVersions(supportedSafariVersion, browser.version) >= 0) {
5465
+ } else if (browser.name === "Safari" && compareVersions(browser.version, supportedSafariVersion) >= 0) {
5399
5466
  return true;
5400
5467
  } else {
5401
5468
  return false;
@@ -5574,13 +5641,13 @@ function unwrapConstraint(constraint) {
5574
5641
  if (Array.isArray(constraint)) {
5575
5642
  return constraint[0];
5576
5643
  }
5577
- if (constraint.exact) {
5644
+ if (constraint.exact !== void 0) {
5578
5645
  if (Array.isArray(constraint.exact)) {
5579
5646
  return constraint.exact[0];
5580
5647
  }
5581
5648
  return constraint.exact;
5582
5649
  }
5583
- if (constraint.ideal) {
5650
+ if (constraint.ideal !== void 0) {
5584
5651
  if (Array.isArray(constraint.ideal)) {
5585
5652
  return constraint.ideal[0];
5586
5653
  }
@@ -5803,7 +5870,7 @@ function constraintsForOptions(options) {
5803
5870
  function detectSilence(track_1) {
5804
5871
  return __awaiter(this, arguments, void 0, function(track) {
5805
5872
  let timeOffset = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 200;
5806
- return function* () {
5873
+ return (function* () {
5807
5874
  const ctx = getNewAudioContext();
5808
5875
  if (ctx) {
5809
5876
  const analyser = ctx.createAnalyser();
@@ -5819,7 +5886,7 @@ function detectSilence(track_1) {
5819
5886
  return !someNoise;
5820
5887
  }
5821
5888
  return false;
5822
- }();
5889
+ })();
5823
5890
  });
5824
5891
  }
5825
5892
  function getNewAudioContext() {
@@ -7543,7 +7610,7 @@ function isIPPrivate(address) {
7543
7610
  }
7544
7611
  return false;
7545
7612
  }
7546
- var e, h, o, _, FLOAT32_MAX, FLOAT32_MIN, UINT32_MAX, INT32_MAX, INT32_MIN, enumTypeSymbol, Message, TWO_PWR_32_DBL, decimalFrom1e7WithLeadingZeros, protoInt64, ScalarType, LongType, WireType, BinaryWriter, BinaryReader, encTable, decTable, protoBase64, jsonReadDefaults, jsonWriteDefaults, tokenNull, tokenIgnoredUnknownEnum, unknownFieldsSymbol, readDefaults, writeDefaults, InternalFieldList, fieldJsonName, reservedObjectProperties, reservedMessageProperties, fallback, safeMessageProperty, safeObjectProperty, InternalOneofInfo, proto3, Timestamp, MetricsBatch, TimeSeriesMetric, MetricSample, EventMetric, BackupCodecPolicy$1, TrackType, TrackSource, VideoQuality$1, ConnectionQuality$1, ClientConfigSetting, DisconnectReason, ReconnectReason, SubscriptionError, AudioTrackFeature, Room$1, Codec, ParticipantPermission, ParticipantInfo, ParticipantInfo_State, ParticipantInfo_Kind, ParticipantInfo_KindDetail, Encryption_Type, SimulcastCodecInfo, TrackInfo, VideoLayer, DataPacket, DataPacket_Kind, ActiveSpeakerUpdate, SpeakerInfo, UserPacket, SipDTMF, Transcription, TranscriptionSegment, ChatMessage, RpcRequest, RpcAck, RpcResponse, RpcError$1, ParticipantTracks, ServerInfo, ServerInfo_Edition, ClientInfo, ClientInfo_SDK, ClientConfiguration, VideoConfiguration, DisabledCodecs, TimedVersion, DataStream_OperationType, DataStream_TextHeader, DataStream_ByteHeader, DataStream_Header, DataStream_Chunk, DataStream_Trailer, SignalTarget, StreamState, CandidateProtocol, SignalRequest, SignalResponse, SimulcastCodec, AddTrackRequest, TrickleRequest, MuteTrackRequest, JoinResponse, ReconnectResponse, TrackPublishedResponse, TrackUnpublishedResponse, SessionDescription, ParticipantUpdate, UpdateSubscription, UpdateTrackSettings, UpdateLocalAudioTrack, UpdateLocalVideoTrack, LeaveRequest, LeaveRequest_Action, UpdateVideoLayers, UpdateParticipantMetadata, ICEServer, SpeakersChanged, RoomUpdate, ConnectionQualityInfo, ConnectionQualityUpdate, StreamStateInfo, StreamStateUpdate, SubscribedQuality, SubscribedCodec, SubscribedQualityUpdate, TrackPermission, SubscriptionPermission, SubscriptionPermissionUpdate, RoomMovedResponse, SyncState, DataChannelReceiveState, DataChannelInfo, SimulateScenario, Ping, Pong, RegionSettings, RegionInfo, SubscriptionResponse, RequestResponse, RequestResponse_Reason, TrackSubscribed, loglevel$1, loglevel, hasRequiredLoglevel, loglevelExports, LogLevel, LoggerNames, livekitLogger, livekitLoggers, workerLogger, maxRetryDelay, DEFAULT_RETRY_DELAYS_IN_MS, DefaultReconnectPolicy, events, hasRequiredEvents, eventsExports, logDisabled_, deprecationWarnings_, logging, chromeShim, firefoxShim, safariShim, sdp$1, hasRequiredSdp, sdpExports, SDPUtils, sdp, commonShim, DECRYPTION_FAILURE_TOLERANCE, E2EE_FLAG, SALT, KEY_PROVIDER_DEFAULTS, KeyProviderEvent, KeyHandlerEvent, EncryptionEvent, CryptorEvent, BaseKeyProvider, LivekitError, ConnectionErrorReason, ConnectionError, DeviceUnsupportedError, TrackInvalidError, UnsupportedServer, UnexpectedConnectionState, NegotiationError, PublishTrackError, SignalRequestError, MediaDeviceFailure, CryptorErrorReason, RoomEvent, ParticipantEvent, EngineEvent, TrackEvent, commonVersionIdentifier, browserDetails, browsersList, version$1, version, protocolVersion, CriticalTimers, BACKGROUND_REACTION_DELAY, recycledElements, VideoQuality, Track, VideoPreset, backupCodecs, videoCodecs, BackupCodecPolicy, AudioPresets, VideoPresets, VideoPresets43, ScreenSharePresets, separator, ddExtensionURI, resizeObserver, getResizeObserver, intersectionObserver, getIntersectionObserver, emptyAudioStreamTrack, Future, E2EEManager, defaultId, DeviceManager, QueueTaskStatus, AsyncQueue, passThroughQueueSignals, SignalConnectionState, SignalClient, DataPacketBuffer, TTLMap, lib, parser, grammar, hasRequiredGrammar, hasRequiredParser, writer, hasRequiredWriter, hasRequiredLib, libExports, startBitrateForSVC, debounceInterval, PCEvents, PCTransport, defaultVideoCodec, publishDefaults, audioDefaults, videoDefaults, roomOptionDefaults, roomConnectOptionDefaults, PCTransportState, PCTransportManager, RpcError, MAX_PAYLOAD_BYTES, monitorFrequency, isMediaRecorderAvailable, FallbackRecorder, RecorderBase, LocalTrackRecorder, DEFAULT_DIMENSIONS_TIMEOUT, PRE_CONNECT_BUFFER_TIMEOUT, LocalTrack, LocalAudioTrack, presets169, presets43, presetsScreenShare, defaultSimulcastPresets169, defaultSimulcastPresets43, computeDefaultScreenShareSimulcastPresets, videoRids, ScalabilityMode, refreshSubscribedCodecAfterNewCodec, LocalVideoTrack, lossyDataChannel, reliableDataChannel, minReconnectWait, leaveReconnect, reliabeReceiveStateTTL, PCState, RTCEngine, SignalReconnectError, RegionUrlProvider, BaseStreamReader, ByteStreamReader, TextStreamReader, BaseStreamWriter, TextStreamWriter, ByteStreamWriter, RemoteTrack, RemoteAudioTrack, REACTION_DELAY, RemoteVideoTrack, HTMLElementInfo, TrackPublication, LocalTrackPublication, ConnectionQuality, Participant, STREAM_CHUNK_SIZE, LocalParticipant, RemoteTrackPublication, RemoteParticipant, ConnectionState, connectionReconcileFrequency, Room, CheckStatus, Checker, CloudRegionCheck, TEST_DURATION, ConnectionProtocolCheck, PublishAudioCheck, PublishVideoCheck, ReconnectCheck, TURNCheck, WebRTCCheck, WebSocketCheck, ConnectionCheck;
7613
+ var e, h, o, _, FLOAT32_MAX, FLOAT32_MIN, UINT32_MAX, INT32_MAX, INT32_MIN, enumTypeSymbol, Message, TWO_PWR_32_DBL, decimalFrom1e7WithLeadingZeros, protoInt64, ScalarType, LongType, WireType, BinaryWriter, BinaryReader, encTable, decTable, protoBase64, jsonReadDefaults, jsonWriteDefaults, tokenNull, tokenIgnoredUnknownEnum, unknownFieldsSymbol, readDefaults, writeDefaults, InternalFieldList, fieldJsonName, reservedObjectProperties, reservedMessageProperties, fallback, safeMessageProperty, safeObjectProperty, InternalOneofInfo, proto3, Timestamp, MetricsBatch, TimeSeriesMetric, MetricSample, EventMetric, BackupCodecPolicy$1, TrackType, TrackSource, VideoQuality$1, ConnectionQuality$1, ClientConfigSetting, DisconnectReason, ReconnectReason, SubscriptionError, AudioTrackFeature, Room$1, Codec, ParticipantPermission, ParticipantInfo, ParticipantInfo_State, ParticipantInfo_Kind, ParticipantInfo_KindDetail, Encryption_Type, SimulcastCodecInfo, TrackInfo, VideoLayer, DataPacket, DataPacket_Kind, ActiveSpeakerUpdate, SpeakerInfo, UserPacket, SipDTMF, Transcription, TranscriptionSegment, ChatMessage, RpcRequest, RpcAck, RpcResponse, RpcError$1, ParticipantTracks, ServerInfo, ServerInfo_Edition, ClientInfo, ClientInfo_SDK, ClientConfiguration, VideoConfiguration, DisabledCodecs, TimedVersion, DataStream_OperationType, DataStream_TextHeader, DataStream_ByteHeader, DataStream_Header, DataStream_Chunk, DataStream_Trailer, SignalTarget, StreamState, CandidateProtocol, SignalRequest, SignalResponse, SimulcastCodec, AddTrackRequest, TrickleRequest, MuteTrackRequest, JoinResponse, ReconnectResponse, TrackPublishedResponse, TrackUnpublishedResponse, SessionDescription, ParticipantUpdate, UpdateSubscription, UpdateTrackSettings, UpdateLocalAudioTrack, UpdateLocalVideoTrack, LeaveRequest, LeaveRequest_Action, UpdateVideoLayers, UpdateParticipantMetadata, ICEServer, SpeakersChanged, RoomUpdate, ConnectionQualityInfo, ConnectionQualityUpdate, StreamStateInfo, StreamStateUpdate, SubscribedQuality, SubscribedCodec, SubscribedQualityUpdate, TrackPermission, SubscriptionPermission, SubscriptionPermissionUpdate, RoomMovedResponse, SyncState, DataChannelReceiveState, DataChannelInfo, SimulateScenario, Ping, Pong, RegionSettings, RegionInfo, SubscriptionResponse, RequestResponse, RequestResponse_Reason, TrackSubscribed, loglevel$1, loglevel, hasRequiredLoglevel, loglevelExports, LogLevel, LoggerNames, livekitLogger, livekitLoggers, workerLogger, maxRetryDelay, DEFAULT_RETRY_DELAYS_IN_MS, DefaultReconnectPolicy, events, hasRequiredEvents, eventsExports, logDisabled_, deprecationWarnings_, logging, chromeShim, firefoxShim, safariShim, sdp$1, hasRequiredSdp, sdpExports, SDPUtils, sdp, commonShim, DECRYPTION_FAILURE_TOLERANCE, E2EE_FLAG, SALT, KEY_PROVIDER_DEFAULTS, KeyProviderEvent, KeyHandlerEvent, EncryptionEvent, CryptorEvent, BaseKeyProvider, LivekitError, ConnectionErrorReason, ConnectionError, DeviceUnsupportedError, TrackInvalidError, UnsupportedServer, UnexpectedConnectionState, NegotiationError, PublishTrackError, SignalRequestError, DataStreamErrorReason, DataStreamError, MediaDeviceFailure, CryptorErrorReason, RoomEvent, ParticipantEvent, EngineEvent, TrackEvent, commonVersionIdentifier, browserDetails, browsersList, version$1, version, protocolVersion, CriticalTimers, BACKGROUND_REACTION_DELAY, recycledElements, VideoQuality, Track, VideoPreset, backupCodecs, videoCodecs, BackupCodecPolicy, AudioPresets, VideoPresets, VideoPresets43, ScreenSharePresets, separator, ddExtensionURI, resizeObserver, getResizeObserver, intersectionObserver, getIntersectionObserver, emptyAudioStreamTrack, Future, E2EEManager, defaultId, DeviceManager, QueueTaskStatus, AsyncQueue, passThroughQueueSignals, SignalConnectionState, SignalClient, DataPacketBuffer, TTLMap, lib, parser, grammar, hasRequiredGrammar, hasRequiredParser, writer, hasRequiredWriter, hasRequiredLib, libExports, startBitrateForSVC, debounceInterval, PCEvents, PCTransport, defaultVideoCodec, publishDefaults, audioDefaults, videoDefaults, roomOptionDefaults, roomConnectOptionDefaults, PCTransportState, PCTransportManager, RpcError, MAX_PAYLOAD_BYTES, monitorFrequency, isMediaRecorderAvailable, FallbackRecorder, RecorderBase, LocalTrackRecorder, DEFAULT_DIMENSIONS_TIMEOUT, PRE_CONNECT_BUFFER_TIMEOUT, LocalTrack, LocalAudioTrack, presets169, presets43, presetsScreenShare, defaultSimulcastPresets169, defaultSimulcastPresets43, computeDefaultScreenShareSimulcastPresets, videoRids, ScalabilityMode, refreshSubscribedCodecAfterNewCodec, LocalVideoTrack, lossyDataChannel, reliableDataChannel, minReconnectWait, leaveReconnect, reliabeReceiveStateTTL, PCState, RTCEngine, SignalReconnectError, RegionUrlProvider, BaseStreamReader, ByteStreamReader, TextStreamReader, IncomingDataStreamManager, BaseStreamWriter, TextStreamWriter, ByteStreamWriter, STREAM_CHUNK_SIZE, OutgoingDataStreamManager, RemoteTrack, RemoteAudioTrack, REACTION_DELAY, RemoteVideoTrack, HTMLElementInfo, TrackPublication, LocalTrackPublication, ConnectionQuality, Participant, LocalParticipant, RemoteTrackPublication, RemoteParticipant, ConnectionState, connectionReconcileFrequency, Room, CheckStatus, Checker, CloudRegionCheck, TEST_DURATION, ConnectionProtocolCheck, PublishAudioCheck, PublishVideoCheck, ReconnectCheck, TURNCheck, WebRTCCheck, WebSocketCheck, ConnectionCheck;
7547
7614
  var init_livekit_client_esm = __esm({
7548
7615
  "node_modules/livekit-client/dist/livekit-client.esm.mjs"() {
7549
7616
  "use strict";
@@ -11419,6 +11486,22 @@ var init_livekit_client_esm = __esm({
11419
11486
  this.reasonName = typeof reason === "string" ? reason : RequestResponse_Reason[reason];
11420
11487
  }
11421
11488
  };
11489
+ (function(DataStreamErrorReason2) {
11490
+ DataStreamErrorReason2[DataStreamErrorReason2["AlreadyOpened"] = 0] = "AlreadyOpened";
11491
+ DataStreamErrorReason2[DataStreamErrorReason2["AbnormalEnd"] = 1] = "AbnormalEnd";
11492
+ DataStreamErrorReason2[DataStreamErrorReason2["DecodeFailed"] = 2] = "DecodeFailed";
11493
+ DataStreamErrorReason2[DataStreamErrorReason2["LengthExceeded"] = 3] = "LengthExceeded";
11494
+ DataStreamErrorReason2[DataStreamErrorReason2["Incomplete"] = 4] = "Incomplete";
11495
+ DataStreamErrorReason2[DataStreamErrorReason2["HandlerAlreadyRegistered"] = 7] = "HandlerAlreadyRegistered";
11496
+ })(DataStreamErrorReason || (DataStreamErrorReason = {}));
11497
+ DataStreamError = class extends LivekitError {
11498
+ constructor(message, reason) {
11499
+ super(16, message);
11500
+ this.name = "DataStreamError";
11501
+ this.reason = reason;
11502
+ this.reasonName = DataStreamErrorReason[reason];
11503
+ }
11504
+ };
11422
11505
  (function(MediaDeviceFailure2) {
11423
11506
  MediaDeviceFailure2["PermissionDenied"] = "PermissionDenied";
11424
11507
  MediaDeviceFailure2["NotFound"] = "NotFound";
@@ -11630,7 +11713,7 @@ var init_livekit_client_esm = __esm({
11630
11713
  }
11631
11714
  }
11632
11715
  ];
11633
- version$1 = "2.15.4";
11716
+ version$1 = "2.15.6";
11634
11717
  version = version$1;
11635
11718
  protocolVersion = 16;
11636
11719
  CriticalTimers = class {
@@ -11656,13 +11739,24 @@ var init_livekit_client_esm = __esm({
11656
11739
  VideoQuality2[VideoQuality2["HIGH"] = 2] = "HIGH";
11657
11740
  })(VideoQuality || (VideoQuality = {}));
11658
11741
  Track = class _Track extends eventsExports.EventEmitter {
11742
+ /**
11743
+ * indicates current state of stream, it'll indicate `paused` if the track
11744
+ * has been paused by congestion controller
11745
+ */
11746
+ get streamState() {
11747
+ return this._streamState;
11748
+ }
11749
+ /** @internal */
11750
+ setStreamState(value) {
11751
+ this._streamState = value;
11752
+ }
11659
11753
  constructor(mediaTrack, kind) {
11660
11754
  let loggerOptions = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {};
11661
11755
  var _a;
11662
11756
  super();
11663
11757
  this.attachedElements = [];
11664
11758
  this.isMuted = false;
11665
- this.streamState = _Track.StreamState.Active;
11759
+ this._streamState = _Track.StreamState.Active;
11666
11760
  this.isInBackground = false;
11667
11761
  this._currentBitrate = 0;
11668
11762
  this.log = livekitLogger;
@@ -12195,6 +12289,20 @@ var init_livekit_client_esm = __esm({
12195
12289
  room2.localParticipant.on(ParticipantEvent.LocalSenderCreated, (sender, track) => __awaiter(this, void 0, void 0, function* () {
12196
12290
  this.setupE2EESender(track, sender);
12197
12291
  }));
12292
+ room2.localParticipant.on(ParticipantEvent.LocalTrackPublished, (publication) => {
12293
+ if (!isVideoTrack(publication.track) || !isSafariBased()) {
12294
+ return;
12295
+ }
12296
+ const msg = {
12297
+ kind: "updateCodec",
12298
+ data: {
12299
+ trackId: publication.track.mediaStreamID,
12300
+ codec: mimeTypeToVideoCodecString(publication.trackInfo.codecs[0].mimeType),
12301
+ participantIdentity: this.room.localParticipant.identity
12302
+ }
12303
+ };
12304
+ this.worker.postMessage(msg);
12305
+ });
12198
12306
  keyProvider.on(KeyProviderEvent.SetKey, (keyInfo) => this.postKey(keyInfo)).on(KeyProviderEvent.RatchetRequest, (participantId, keyIndex) => this.postRatchetRequest(participantId, keyIndex));
12199
12307
  }
12200
12308
  postRatchetRequest(participantIdentity, keyIndex) {
@@ -12405,7 +12513,7 @@ var init_livekit_client_esm = __esm({
12405
12513
  return __awaiter(this, arguments, void 0, function(kind) {
12406
12514
  var _this = this;
12407
12515
  let requestPermissions = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
12408
- return function* () {
12516
+ return (function* () {
12409
12517
  var _a;
12410
12518
  if (((_a = _DeviceManager.userMediaPromiseMap) === null || _a === void 0 ? void 0 : _a.size) > 0) {
12411
12519
  livekitLogger.debug("awaiting getUserMedia promise");
@@ -12448,7 +12556,7 @@ var init_livekit_client_esm = __esm({
12448
12556
  devices = devices.filter((device) => device.kind === kind);
12449
12557
  }
12450
12558
  return devices;
12451
- }();
12559
+ })();
12452
12560
  });
12453
12561
  }
12454
12562
  normalizeDeviceId(kind, deviceId, groupId) {
@@ -12729,7 +12837,7 @@ var init_livekit_client_esm = __esm({
12729
12837
  return __awaiter(this, arguments, void 0, function() {
12730
12838
  var _this = this;
12731
12839
  let updateState = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : true;
12732
- return function* () {
12840
+ return (function* () {
12733
12841
  const unlock = yield _this.closingLock.lock();
12734
12842
  try {
12735
12843
  _this.clearPingInterval();
@@ -12761,7 +12869,7 @@ var init_livekit_client_esm = __esm({
12761
12869
  }
12762
12870
  unlock();
12763
12871
  }
12764
- }();
12872
+ })();
12765
12873
  });
12766
12874
  }
12767
12875
  // initial offer after joining
@@ -12815,7 +12923,7 @@ var init_livekit_client_esm = __esm({
12815
12923
  return __awaiter(this, arguments, void 0, function(metadata, name2) {
12816
12924
  var _this2 = this;
12817
12925
  let attributes = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {};
12818
- return function* () {
12926
+ return (function* () {
12819
12927
  const requestId = _this2.getNextRequestId();
12820
12928
  yield _this2.sendRequest({
12821
12929
  case: "updateMetadata",
@@ -12827,7 +12935,7 @@ var init_livekit_client_esm = __esm({
12827
12935
  })
12828
12936
  });
12829
12937
  return requestId;
12830
- }();
12938
+ })();
12831
12939
  });
12832
12940
  }
12833
12941
  sendUpdateTrackSettings(settings) {
@@ -12907,7 +13015,7 @@ var init_livekit_client_esm = __esm({
12907
13015
  return __awaiter(this, arguments, void 0, function(message) {
12908
13016
  var _this3 = this;
12909
13017
  let fromQueue = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false;
12910
- return function* () {
13018
+ return (function* () {
12911
13019
  const canQueue = !fromQueue && !canPassThroughQueue(message);
12912
13020
  if (canQueue && _this3.state === SignalConnectionState.RECONNECTING) {
12913
13021
  _this3.queuedRequests.push(() => __awaiter(_this3, void 0, void 0, function* () {
@@ -12943,7 +13051,7 @@ var init_livekit_client_esm = __esm({
12943
13051
  error: e3
12944
13052
  }));
12945
13053
  }
12946
- }();
13054
+ })();
12947
13055
  });
12948
13056
  }
12949
13057
  handleSignalResponse(res) {
@@ -14009,7 +14117,7 @@ var init_livekit_client_esm = __esm({
14009
14117
  return __awaiter(this, arguments, void 0, function(pcTransport, abortController) {
14010
14118
  var _this = this;
14011
14119
  let timeout = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : this.peerConnectionTimeout;
14012
- return function* () {
14120
+ return (function* () {
14013
14121
  const connectionState = pcTransport.getConnectionState();
14014
14122
  if (connectionState === "connected") {
14015
14123
  return;
@@ -14039,7 +14147,7 @@ var init_livekit_client_esm = __esm({
14039
14147
  abortController === null || abortController === void 0 ? void 0 : abortController.signal.removeEventListener("abort", abortHandler);
14040
14148
  resolve();
14041
14149
  }));
14042
- }();
14150
+ })();
14043
14151
  });
14044
14152
  }
14045
14153
  };
@@ -14220,9 +14328,14 @@ var init_livekit_client_esm = __esm({
14220
14328
  this.providedByUser = userProvidedTrack;
14221
14329
  this.muteLock = new _();
14222
14330
  this.pauseUpstreamLock = new _();
14223
- this.processorLock = new _();
14224
- this.restartLock = new _();
14225
- this.setMediaStreamTrack(mediaTrack, true);
14331
+ this.trackChangeLock = new _();
14332
+ this.trackChangeLock.lock().then((unlock) => __awaiter(this, void 0, void 0, function* () {
14333
+ try {
14334
+ yield this.setMediaStreamTrack(mediaTrack, true);
14335
+ } finally {
14336
+ unlock();
14337
+ }
14338
+ }));
14226
14339
  this._constraints = mediaTrack.getConstraints();
14227
14340
  if (constraints) {
14228
14341
  this._constraints = constraints;
@@ -14291,25 +14404,20 @@ var init_livekit_client_esm = __esm({
14291
14404
  }
14292
14405
  let processedTrack;
14293
14406
  if (this.processor && newTrack) {
14294
- const unlock = yield this.processorLock.lock();
14295
- try {
14296
- this.log.debug("restarting processor", this.logContext);
14297
- if (this.kind === "unknown") {
14298
- throw TypeError("cannot set processor on track of unknown kind");
14299
- }
14300
- if (this.processorElement) {
14301
- attachToElement(newTrack, this.processorElement);
14302
- this.processorElement.muted = true;
14303
- }
14304
- yield this.processor.restart({
14305
- track: newTrack,
14306
- kind: this.kind,
14307
- element: this.processorElement
14308
- });
14309
- processedTrack = this.processor.processedTrack;
14310
- } finally {
14311
- unlock();
14407
+ this.log.debug("restarting processor", this.logContext);
14408
+ if (this.kind === "unknown") {
14409
+ throw TypeError("cannot set processor on track of unknown kind");
14410
+ }
14411
+ if (this.processorElement) {
14412
+ attachToElement(newTrack, this.processorElement);
14413
+ this.processorElement.muted = true;
14312
14414
  }
14415
+ yield this.processor.restart({
14416
+ track: newTrack,
14417
+ kind: this.kind,
14418
+ element: this.processorElement
14419
+ });
14420
+ processedTrack = this.processor.processedTrack;
14313
14421
  }
14314
14422
  if (this.sender && ((_a = this.sender.transport) === null || _a === void 0 ? void 0 : _a.state) !== "closed") {
14315
14423
  yield this.sender.replaceTrack(processedTrack !== null && processedTrack !== void 0 ? processedTrack : newTrack);
@@ -14331,7 +14439,7 @@ var init_livekit_client_esm = __esm({
14331
14439
  return __awaiter(this, arguments, void 0, function() {
14332
14440
  var _this = this;
14333
14441
  let timeout = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : DEFAULT_DIMENSIONS_TIMEOUT;
14334
- return function* () {
14442
+ return (function* () {
14335
14443
  var _a;
14336
14444
  if (_this.kind === Track.Kind.Audio) {
14337
14445
  throw new Error("cannot get dimensions for audio tracks");
@@ -14348,7 +14456,7 @@ var init_livekit_client_esm = __esm({
14348
14456
  yield sleep(50);
14349
14457
  }
14350
14458
  throw new TrackInvalidError("unable to get track dimensions after timeout");
14351
- }();
14459
+ })();
14352
14460
  });
14353
14461
  }
14354
14462
  setDeviceId(deviceId) {
@@ -14371,7 +14479,7 @@ var init_livekit_client_esm = __esm({
14371
14479
  return __awaiter(this, arguments, void 0, function() {
14372
14480
  var _this2 = this;
14373
14481
  let normalize3 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : true;
14374
- return function* () {
14482
+ return (function* () {
14375
14483
  if (_this2.source === Track.Source.ScreenShare) {
14376
14484
  return;
14377
14485
  }
@@ -14381,7 +14489,7 @@ var init_livekit_client_esm = __esm({
14381
14489
  } = _this2._mediaStreamTrack.getSettings();
14382
14490
  const kind = _this2.kind === Track.Kind.Audio ? "audioinput" : "videoinput";
14383
14491
  return normalize3 ? DeviceManager.getInstance().normalizeDeviceId(kind, deviceId, groupId) : deviceId;
14384
- }();
14492
+ })();
14385
14493
  });
14386
14494
  }
14387
14495
  mute() {
@@ -14398,30 +14506,35 @@ var init_livekit_client_esm = __esm({
14398
14506
  }
14399
14507
  replaceTrack(track, userProvidedOrOptions) {
14400
14508
  return __awaiter(this, void 0, void 0, function* () {
14401
- if (!this.sender) {
14402
- throw new TrackInvalidError("unable to replace an unpublished track");
14403
- }
14404
- let userProvidedTrack;
14405
- let stopProcessor;
14406
- if (typeof userProvidedOrOptions === "boolean") {
14407
- userProvidedTrack = userProvidedOrOptions;
14408
- } else if (userProvidedOrOptions !== void 0) {
14409
- userProvidedTrack = userProvidedOrOptions.userProvidedTrack;
14410
- stopProcessor = userProvidedOrOptions.stopProcessor;
14411
- }
14412
- this.providedByUser = userProvidedTrack !== null && userProvidedTrack !== void 0 ? userProvidedTrack : true;
14413
- this.log.debug("replace MediaStreamTrack", this.logContext);
14414
- yield this.setMediaStreamTrack(track);
14415
- if (stopProcessor && this.processor) {
14416
- yield this.stopProcessor();
14509
+ const unlock = yield this.trackChangeLock.lock();
14510
+ try {
14511
+ if (!this.sender) {
14512
+ throw new TrackInvalidError("unable to replace an unpublished track");
14513
+ }
14514
+ let userProvidedTrack;
14515
+ let stopProcessor;
14516
+ if (typeof userProvidedOrOptions === "boolean") {
14517
+ userProvidedTrack = userProvidedOrOptions;
14518
+ } else if (userProvidedOrOptions !== void 0) {
14519
+ userProvidedTrack = userProvidedOrOptions.userProvidedTrack;
14520
+ stopProcessor = userProvidedOrOptions.stopProcessor;
14521
+ }
14522
+ this.providedByUser = userProvidedTrack !== null && userProvidedTrack !== void 0 ? userProvidedTrack : true;
14523
+ this.log.debug("replace MediaStreamTrack", this.logContext);
14524
+ yield this.setMediaStreamTrack(track);
14525
+ if (stopProcessor && this.processor) {
14526
+ yield this.internalStopProcessor();
14527
+ }
14528
+ return this;
14529
+ } finally {
14530
+ unlock();
14417
14531
  }
14418
- return this;
14419
14532
  });
14420
14533
  }
14421
14534
  restart(constraints) {
14422
14535
  return __awaiter(this, void 0, void 0, function* () {
14423
14536
  this.manuallyStopped = false;
14424
- const unlock = yield this.restartLock.lock();
14537
+ const unlock = yield this.trackChangeLock.lock();
14425
14538
  try {
14426
14539
  if (!constraints) {
14427
14540
  constraints = this._constraints;
@@ -14443,9 +14556,9 @@ var init_livekit_client_esm = __esm({
14443
14556
  facingMode
14444
14557
  } : true;
14445
14558
  } else {
14446
- streamConstraints.audio = deviceId ? {
14559
+ streamConstraints.audio = deviceId ? Object.assign({
14447
14560
  deviceId
14448
- } : true;
14561
+ }, otherConstraints) : true;
14449
14562
  }
14450
14563
  this.attachedElements.forEach((el) => {
14451
14564
  detachTrack(this.mediaStreamTrack, el);
@@ -14454,7 +14567,9 @@ var init_livekit_client_esm = __esm({
14454
14567
  this._mediaStreamTrack.stop();
14455
14568
  const mediaStream = yield navigator.mediaDevices.getUserMedia(streamConstraints);
14456
14569
  const newTrack = mediaStream.getTracks()[0];
14457
- yield newTrack.applyConstraints(otherConstraints);
14570
+ if (this.kind === Track.Kind.Video) {
14571
+ yield newTrack.applyConstraints(otherConstraints);
14572
+ }
14458
14573
  newTrack.addEventListener("ended", this.handleEnded);
14459
14574
  this.log.debug("re-acquired MediaStreamTrack", this.logContext);
14460
14575
  yield this.setMediaStreamTrack(newTrack);
@@ -14593,9 +14708,9 @@ var init_livekit_client_esm = __esm({
14593
14708
  return __awaiter(this, arguments, void 0, function(processor) {
14594
14709
  var _this3 = this;
14595
14710
  let showProcessedStreamLocally = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
14596
- return function* () {
14711
+ return (function* () {
14597
14712
  var _a;
14598
- const unlock = yield _this3.processorLock.lock();
14713
+ const unlock = yield _this3.trackChangeLock.lock();
14599
14714
  try {
14600
14715
  _this3.log.debug("setting up processor", _this3.logContext);
14601
14716
  const processorElement = document.createElement(_this3.kind);
@@ -14608,7 +14723,7 @@ var init_livekit_client_esm = __esm({
14608
14723
  yield processor.init(processorOptions);
14609
14724
  _this3.log.debug("processor initialized", _this3.logContext);
14610
14725
  if (_this3.processor) {
14611
- yield _this3.stopProcessor();
14726
+ yield _this3.internalStopProcessor();
14612
14727
  }
14613
14728
  if (_this3.kind === "unknown") {
14614
14729
  throw TypeError("cannot set processor on track of unknown kind");
@@ -14648,7 +14763,7 @@ var init_livekit_client_esm = __esm({
14648
14763
  } finally {
14649
14764
  unlock();
14650
14765
  }
14651
- }();
14766
+ })();
14652
14767
  });
14653
14768
  }
14654
14769
  getProcessor() {
@@ -14665,21 +14780,40 @@ var init_livekit_client_esm = __esm({
14665
14780
  return __awaiter(this, arguments, void 0, function() {
14666
14781
  var _this4 = this;
14667
14782
  let keepElement = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : true;
14668
- return function* () {
14783
+ return (function* () {
14784
+ const unlock = yield _this4.trackChangeLock.lock();
14785
+ try {
14786
+ yield _this4.internalStopProcessor(keepElement);
14787
+ } finally {
14788
+ unlock();
14789
+ }
14790
+ })();
14791
+ });
14792
+ }
14793
+ /**
14794
+ * @internal
14795
+ * This method assumes the caller has acquired a trackChangeLock already.
14796
+ * The public facing method for stopping the processor is `stopProcessor` and it wraps this method in the trackChangeLock.
14797
+ */
14798
+ internalStopProcessor() {
14799
+ return __awaiter(this, arguments, void 0, function() {
14800
+ var _this5 = this;
14801
+ let keepElement = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : true;
14802
+ return (function* () {
14669
14803
  var _a, _b;
14670
- if (!_this4.processor) return;
14671
- _this4.log.debug("stopping processor", _this4.logContext);
14672
- (_a = _this4.processor.processedTrack) === null || _a === void 0 ? void 0 : _a.stop();
14673
- yield _this4.processor.destroy();
14674
- _this4.processor = void 0;
14804
+ if (!_this5.processor) return;
14805
+ _this5.log.debug("stopping processor", _this5.logContext);
14806
+ (_a = _this5.processor.processedTrack) === null || _a === void 0 ? void 0 : _a.stop();
14807
+ yield _this5.processor.destroy();
14808
+ _this5.processor = void 0;
14675
14809
  if (!keepElement) {
14676
- (_b = _this4.processorElement) === null || _b === void 0 ? void 0 : _b.remove();
14677
- _this4.processorElement = void 0;
14810
+ (_b = _this5.processorElement) === null || _b === void 0 ? void 0 : _b.remove();
14811
+ _this5.processorElement = void 0;
14678
14812
  }
14679
- yield _this4._mediaStreamTrack.applyConstraints(_this4._constraints);
14680
- yield _this4.setMediaStreamTrack(_this4._mediaStreamTrack, true);
14681
- _this4.emit(TrackEvent.TrackProcessorUpdate);
14682
- }();
14813
+ yield _this5._mediaStreamTrack.applyConstraints(_this5._constraints);
14814
+ yield _this5.setMediaStreamTrack(_this5._mediaStreamTrack, true);
14815
+ _this5.emit(TrackEvent.TrackProcessorUpdate);
14816
+ })();
14683
14817
  });
14684
14818
  }
14685
14819
  /** @internal */
@@ -14867,13 +15001,13 @@ var init_livekit_client_esm = __esm({
14867
15001
  setProcessor(processor) {
14868
15002
  return __awaiter(this, void 0, void 0, function* () {
14869
15003
  var _a;
14870
- const unlock = yield this.processorLock.lock();
15004
+ const unlock = yield this.trackChangeLock.lock();
14871
15005
  try {
14872
15006
  if (!isReactNative() && !this.audioContext) {
14873
15007
  throw Error("Audio context needs to be set on LocalAudioTrack in order to enable processors");
14874
15008
  }
14875
15009
  if (this.processor) {
14876
- yield this.stopProcessor();
15010
+ yield this.internalStopProcessor();
14877
15011
  }
14878
15012
  const processorOptions = {
14879
15013
  kind: this.kind,
@@ -15288,7 +15422,7 @@ var init_livekit_client_esm = __esm({
15288
15422
  return __awaiter(this, arguments, void 0, function(processor) {
15289
15423
  var _this = this;
15290
15424
  let showProcessedStreamLocally = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
15291
- return function* () {
15425
+ return (function* () {
15292
15426
  var _a, e_4, _b, _c;
15293
15427
  var _d, _e;
15294
15428
  yield _super.setProcessor.call(_this, processor, showProcessedStreamLocally);
@@ -15312,7 +15446,7 @@ var init_livekit_client_esm = __esm({
15312
15446
  }
15313
15447
  }
15314
15448
  }
15315
- }();
15449
+ })();
15316
15450
  });
15317
15451
  }
15318
15452
  setDegradationPreference(preference) {
@@ -15536,7 +15670,7 @@ var init_livekit_client_esm = __esm({
15536
15670
  let {
15537
15671
  channel
15538
15672
  } = _ref;
15539
- return function* () {
15673
+ return (function* () {
15540
15674
  if (!channel) {
15541
15675
  return;
15542
15676
  }
@@ -15549,7 +15683,7 @@ var init_livekit_client_esm = __esm({
15549
15683
  }
15550
15684
  _this.log.debug("on data channel ".concat(channel.id, ", ").concat(channel.label), _this.logContext);
15551
15685
  channel.onmessage = _this.handleDataMessage;
15552
- }();
15686
+ })();
15553
15687
  });
15554
15688
  this.handleDataMessage = (message) => __awaiter(this, void 0, void 0, function* () {
15555
15689
  var _a2, _b;
@@ -16432,7 +16566,7 @@ var init_livekit_client_esm = __esm({
16432
16566
  return __awaiter(this, arguments, void 0, function(kind) {
16433
16567
  var _this2 = this;
16434
16568
  let subscriber = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : this.subscriberPrimary;
16435
- return function* () {
16569
+ return (function* () {
16436
16570
  var _a;
16437
16571
  if (!_this2.pcManager) {
16438
16572
  throw new UnexpectedConnectionState("PC manager is closed");
@@ -16465,7 +16599,7 @@ var init_livekit_client_esm = __esm({
16465
16599
  yield sleep(50);
16466
16600
  }
16467
16601
  throw new ConnectionError("could not establish ".concat(transportName, " connection, state: ").concat(transport.getICEConnectionState()), ConnectionErrorReason.InternalError);
16468
- }();
16602
+ })();
16469
16603
  });
16470
16604
  }
16471
16605
  ensurePublisherConnected(kind) {
@@ -16708,30 +16842,72 @@ var init_livekit_client_esm = __esm({
16708
16842
  get info() {
16709
16843
  return this._info;
16710
16844
  }
16711
- constructor(info, stream, totalByteSize) {
16845
+ /** @internal */
16846
+ validateBytesReceived() {
16847
+ let doneReceiving = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : false;
16848
+ if (typeof this.totalByteSize !== "number" || this.totalByteSize === 0) {
16849
+ return;
16850
+ }
16851
+ if (doneReceiving && this.bytesReceived < this.totalByteSize) {
16852
+ throw new DataStreamError("Not enough chunk(s) received - expected ".concat(this.totalByteSize, " bytes of data total, only received ").concat(this.bytesReceived, " bytes"), DataStreamErrorReason.Incomplete);
16853
+ } else if (this.bytesReceived > this.totalByteSize) {
16854
+ throw new DataStreamError("Extra chunk(s) received - expected ".concat(this.totalByteSize, " bytes of data total, received ").concat(this.bytesReceived, " bytes"), DataStreamErrorReason.LengthExceeded);
16855
+ }
16856
+ }
16857
+ constructor(info, stream, totalByteSize, outOfBandFailureRejectingFuture) {
16712
16858
  this.reader = stream;
16713
16859
  this.totalByteSize = totalByteSize;
16714
16860
  this._info = info;
16715
16861
  this.bytesReceived = 0;
16862
+ this.outOfBandFailureRejectingFuture = outOfBandFailureRejectingFuture;
16716
16863
  }
16717
16864
  };
16718
16865
  ByteStreamReader = class extends BaseStreamReader {
16719
16866
  handleChunkReceived(chunk) {
16720
16867
  var _a;
16721
16868
  this.bytesReceived += chunk.content.byteLength;
16869
+ this.validateBytesReceived();
16722
16870
  const currentProgress = this.totalByteSize ? this.bytesReceived / this.totalByteSize : void 0;
16723
16871
  (_a = this.onProgress) === null || _a === void 0 ? void 0 : _a.call(this, currentProgress);
16724
16872
  }
16725
16873
  [Symbol.asyncIterator]() {
16726
16874
  const reader = this.reader.getReader();
16875
+ let rejectingSignalFuture = new Future();
16876
+ let activeSignal = null;
16877
+ let onAbort = null;
16878
+ if (this.signal) {
16879
+ const signal = this.signal;
16880
+ onAbort = () => {
16881
+ var _a;
16882
+ (_a = rejectingSignalFuture.reject) === null || _a === void 0 ? void 0 : _a.call(rejectingSignalFuture, signal.reason);
16883
+ };
16884
+ signal.addEventListener("abort", onAbort);
16885
+ activeSignal = signal;
16886
+ }
16887
+ const cleanup = () => {
16888
+ reader.releaseLock();
16889
+ if (activeSignal && onAbort) {
16890
+ activeSignal.removeEventListener("abort", onAbort);
16891
+ }
16892
+ this.signal = void 0;
16893
+ };
16727
16894
  return {
16728
16895
  next: () => __awaiter(this, void 0, void 0, function* () {
16896
+ var _a, _b;
16729
16897
  try {
16730
16898
  const {
16731
16899
  done,
16732
16900
  value
16733
- } = yield reader.read();
16901
+ } = yield Promise.race([
16902
+ reader.read(),
16903
+ // Rejects if this.signal is aborted
16904
+ rejectingSignalFuture.promise,
16905
+ // Rejects if something external says it should, like a participant disconnecting, etc
16906
+ (_b = (_a = this.outOfBandFailureRejectingFuture) === null || _a === void 0 ? void 0 : _a.promise) !== null && _b !== void 0 ? _b : new Promise(() => {
16907
+ })
16908
+ ]);
16734
16909
  if (done) {
16910
+ this.validateBytesReceived(true);
16735
16911
  return {
16736
16912
  done: true,
16737
16913
  value: void 0
@@ -16743,16 +16919,16 @@ var init_livekit_client_esm = __esm({
16743
16919
  value: value.content
16744
16920
  };
16745
16921
  }
16746
- } catch (error) {
16747
- return {
16748
- done: true,
16749
- value: void 0
16750
- };
16922
+ } catch (err) {
16923
+ cleanup();
16924
+ throw err;
16751
16925
  }
16752
16926
  }),
16927
+ // note: `return` runs only for premature exits, see:
16928
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#errors_during_iteration
16753
16929
  return() {
16754
16930
  return __awaiter(this, void 0, void 0, function* () {
16755
- reader.releaseLock();
16931
+ cleanup();
16756
16932
  return {
16757
16933
  done: true,
16758
16934
  value: void 0
@@ -16761,29 +16937,45 @@ var init_livekit_client_esm = __esm({
16761
16937
  }
16762
16938
  };
16763
16939
  }
16940
+ /**
16941
+ * Injects an AbortSignal, which if aborted, will terminate the currently active
16942
+ * stream iteration operation.
16943
+ *
16944
+ * Note that when using AbortSignal.timeout(...), the timeout applies across
16945
+ * the whole iteration operation, not just one individual chunk read.
16946
+ */
16947
+ withAbortSignal(signal) {
16948
+ this.signal = signal;
16949
+ return this;
16950
+ }
16764
16951
  readAll() {
16765
- return __awaiter(this, void 0, void 0, function* () {
16766
- var _a, e_1, _b, _c;
16767
- let chunks = /* @__PURE__ */ new Set();
16768
- try {
16769
- for (var _d = true, _e = __asyncValues(this), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
16770
- _c = _f.value;
16771
- _d = false;
16772
- const chunk = _c;
16773
- chunks.add(chunk);
16774
- }
16775
- } catch (e_1_1) {
16776
- e_1 = {
16777
- error: e_1_1
16778
- };
16779
- } finally {
16952
+ return __awaiter(this, arguments, void 0, function() {
16953
+ var _this = this;
16954
+ let opts = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
16955
+ return (function* () {
16956
+ var _a, e_1, _b, _c;
16957
+ let chunks = /* @__PURE__ */ new Set();
16958
+ const iterator = opts.signal ? _this.withAbortSignal(opts.signal) : _this;
16780
16959
  try {
16781
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
16960
+ for (var _d = true, iterator_1 = __asyncValues(iterator), iterator_1_1; iterator_1_1 = yield iterator_1.next(), _a = iterator_1_1.done, !_a; _d = true) {
16961
+ _c = iterator_1_1.value;
16962
+ _d = false;
16963
+ const chunk = _c;
16964
+ chunks.add(chunk);
16965
+ }
16966
+ } catch (e_1_1) {
16967
+ e_1 = {
16968
+ error: e_1_1
16969
+ };
16782
16970
  } finally {
16783
- if (e_1) throw e_1.error;
16971
+ try {
16972
+ if (!_d && !_a && (_b = iterator_1.return)) yield _b.call(iterator_1);
16973
+ } finally {
16974
+ if (e_1) throw e_1.error;
16975
+ }
16784
16976
  }
16785
- }
16786
- return Array.from(chunks);
16977
+ return Array.from(chunks);
16978
+ })();
16787
16979
  });
16788
16980
  }
16789
16981
  };
@@ -16792,8 +16984,8 @@ var init_livekit_client_esm = __esm({
16792
16984
  * A TextStreamReader instance can be used as an AsyncIterator that returns the entire string
16793
16985
  * that has been received up to the current point in time.
16794
16986
  */
16795
- constructor(info, stream, totalChunkCount) {
16796
- super(info, stream, totalChunkCount);
16987
+ constructor(info, stream, totalChunkCount, outOfBandFailureRejectingFuture) {
16988
+ super(info, stream, totalChunkCount, outOfBandFailureRejectingFuture);
16797
16989
  this.receivedChunks = /* @__PURE__ */ new Map();
16798
16990
  }
16799
16991
  handleChunkReceived(chunk) {
@@ -16805,6 +16997,7 @@ var init_livekit_client_esm = __esm({
16805
16997
  }
16806
16998
  this.receivedChunks.set(index2, chunk);
16807
16999
  this.bytesReceived += chunk.content.byteLength;
17000
+ this.validateBytesReceived();
16808
17001
  const currentProgress = this.totalByteSize ? this.bytesReceived / this.totalByteSize : void 0;
16809
17002
  (_a = this.onProgress) === null || _a === void 0 ? void 0 : _a.call(this, currentProgress);
16810
17003
  }
@@ -16815,36 +17008,72 @@ var init_livekit_client_esm = __esm({
16815
17008
  */
16816
17009
  [Symbol.asyncIterator]() {
16817
17010
  const reader = this.reader.getReader();
16818
- const decoder = new TextDecoder();
17011
+ const decoder = new TextDecoder("utf-8", {
17012
+ fatal: true
17013
+ });
17014
+ let rejectingSignalFuture = new Future();
17015
+ let activeSignal = null;
17016
+ let onAbort = null;
17017
+ if (this.signal) {
17018
+ const signal = this.signal;
17019
+ onAbort = () => {
17020
+ var _a;
17021
+ (_a = rejectingSignalFuture.reject) === null || _a === void 0 ? void 0 : _a.call(rejectingSignalFuture, signal.reason);
17022
+ };
17023
+ signal.addEventListener("abort", onAbort);
17024
+ activeSignal = signal;
17025
+ }
17026
+ const cleanup = () => {
17027
+ reader.releaseLock();
17028
+ if (activeSignal && onAbort) {
17029
+ activeSignal.removeEventListener("abort", onAbort);
17030
+ }
17031
+ this.signal = void 0;
17032
+ };
16819
17033
  return {
16820
17034
  next: () => __awaiter(this, void 0, void 0, function* () {
17035
+ var _a, _b;
16821
17036
  try {
16822
17037
  const {
16823
17038
  done,
16824
17039
  value
16825
- } = yield reader.read();
17040
+ } = yield Promise.race([
17041
+ reader.read(),
17042
+ // Rejects if this.signal is aborted
17043
+ rejectingSignalFuture.promise,
17044
+ // Rejects if something external says it should, like a participant disconnecting, etc
17045
+ (_b = (_a = this.outOfBandFailureRejectingFuture) === null || _a === void 0 ? void 0 : _a.promise) !== null && _b !== void 0 ? _b : new Promise(() => {
17046
+ })
17047
+ ]);
16826
17048
  if (done) {
17049
+ this.validateBytesReceived(true);
16827
17050
  return {
16828
17051
  done: true,
16829
17052
  value: void 0
16830
17053
  };
16831
17054
  } else {
16832
17055
  this.handleChunkReceived(value);
17056
+ let decodedResult;
17057
+ try {
17058
+ decodedResult = decoder.decode(value.content);
17059
+ } catch (err) {
17060
+ throw new DataStreamError("Cannot decode datastream chunk ".concat(value.chunkIndex, " as text: ").concat(err), DataStreamErrorReason.DecodeFailed);
17061
+ }
16833
17062
  return {
16834
17063
  done: false,
16835
- value: decoder.decode(value.content)
17064
+ value: decodedResult
16836
17065
  };
16837
17066
  }
16838
- } catch (error) {
16839
- return {
16840
- done: true,
16841
- value: void 0
16842
- };
17067
+ } catch (err) {
17068
+ cleanup();
17069
+ throw err;
16843
17070
  }
16844
17071
  }),
17072
+ // note: `return` runs only for premature exits, see:
17073
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#errors_during_iteration
16845
17074
  return() {
16846
17075
  return __awaiter(this, void 0, void 0, function* () {
16847
- reader.releaseLock();
17076
+ cleanup();
16848
17077
  return {
16849
17078
  done: true,
16850
17079
  value: void 0
@@ -16853,31 +17082,215 @@ var init_livekit_client_esm = __esm({
16853
17082
  }
16854
17083
  };
16855
17084
  }
17085
+ /**
17086
+ * Injects an AbortSignal, which if aborted, will terminate the currently active
17087
+ * stream iteration operation.
17088
+ *
17089
+ * Note that when using AbortSignal.timeout(...), the timeout applies across
17090
+ * the whole iteration operation, not just one individual chunk read.
17091
+ */
17092
+ withAbortSignal(signal) {
17093
+ this.signal = signal;
17094
+ return this;
17095
+ }
16856
17096
  readAll() {
17097
+ return __awaiter(this, arguments, void 0, function() {
17098
+ var _this2 = this;
17099
+ let opts = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
17100
+ return (function* () {
17101
+ var _a, e_2, _b, _c;
17102
+ let finalString = "";
17103
+ const iterator = opts.signal ? _this2.withAbortSignal(opts.signal) : _this2;
17104
+ try {
17105
+ for (var _d = true, iterator_2 = __asyncValues(iterator), iterator_2_1; iterator_2_1 = yield iterator_2.next(), _a = iterator_2_1.done, !_a; _d = true) {
17106
+ _c = iterator_2_1.value;
17107
+ _d = false;
17108
+ const chunk = _c;
17109
+ finalString += chunk;
17110
+ }
17111
+ } catch (e_2_1) {
17112
+ e_2 = {
17113
+ error: e_2_1
17114
+ };
17115
+ } finally {
17116
+ try {
17117
+ if (!_d && !_a && (_b = iterator_2.return)) yield _b.call(iterator_2);
17118
+ } finally {
17119
+ if (e_2) throw e_2.error;
17120
+ }
17121
+ }
17122
+ return finalString;
17123
+ })();
17124
+ });
17125
+ }
17126
+ };
17127
+ IncomingDataStreamManager = class {
17128
+ constructor() {
17129
+ this.log = livekitLogger;
17130
+ this.byteStreamControllers = /* @__PURE__ */ new Map();
17131
+ this.textStreamControllers = /* @__PURE__ */ new Map();
17132
+ this.byteStreamHandlers = /* @__PURE__ */ new Map();
17133
+ this.textStreamHandlers = /* @__PURE__ */ new Map();
17134
+ }
17135
+ registerTextStreamHandler(topic, callback) {
17136
+ if (this.textStreamHandlers.has(topic)) {
17137
+ throw new DataStreamError('A text stream handler for topic "'.concat(topic, '" has already been set.'), DataStreamErrorReason.HandlerAlreadyRegistered);
17138
+ }
17139
+ this.textStreamHandlers.set(topic, callback);
17140
+ }
17141
+ unregisterTextStreamHandler(topic) {
17142
+ this.textStreamHandlers.delete(topic);
17143
+ }
17144
+ registerByteStreamHandler(topic, callback) {
17145
+ if (this.byteStreamHandlers.has(topic)) {
17146
+ throw new DataStreamError('A byte stream handler for topic "'.concat(topic, '" has already been set.'), DataStreamErrorReason.HandlerAlreadyRegistered);
17147
+ }
17148
+ this.byteStreamHandlers.set(topic, callback);
17149
+ }
17150
+ unregisterByteStreamHandler(topic) {
17151
+ this.byteStreamHandlers.delete(topic);
17152
+ }
17153
+ clearHandlersAndControllers() {
17154
+ this.byteStreamControllers.clear();
17155
+ this.textStreamControllers.clear();
17156
+ this.byteStreamHandlers.clear();
17157
+ this.textStreamHandlers.clear();
17158
+ }
17159
+ validateParticipantHasNoActiveDataStreams(participantIdentity) {
17160
+ var _a, _b, _c, _d;
17161
+ const textStreamsBeingSentByDisconnectingParticipant = Array.from(this.textStreamControllers.entries()).filter((entry) => entry[1].sendingParticipantIdentity === participantIdentity);
17162
+ const byteStreamsBeingSentByDisconnectingParticipant = Array.from(this.byteStreamControllers.entries()).filter((entry) => entry[1].sendingParticipantIdentity === participantIdentity);
17163
+ if (textStreamsBeingSentByDisconnectingParticipant.length > 0 || byteStreamsBeingSentByDisconnectingParticipant.length > 0) {
17164
+ const abnormalEndError = new DataStreamError("Participant ".concat(participantIdentity, " unexpectedly disconnected in the middle of sending data"), DataStreamErrorReason.AbnormalEnd);
17165
+ for (const [id, controller] of byteStreamsBeingSentByDisconnectingParticipant) {
17166
+ (_b = (_a = controller.outOfBandFailureRejectingFuture).reject) === null || _b === void 0 ? void 0 : _b.call(_a, abnormalEndError);
17167
+ this.byteStreamControllers.delete(id);
17168
+ }
17169
+ for (const [id, controller] of textStreamsBeingSentByDisconnectingParticipant) {
17170
+ (_d = (_c = controller.outOfBandFailureRejectingFuture).reject) === null || _d === void 0 ? void 0 : _d.call(_c, abnormalEndError);
17171
+ this.textStreamControllers.delete(id);
17172
+ }
17173
+ }
17174
+ }
17175
+ handleDataStreamPacket(packet) {
16857
17176
  return __awaiter(this, void 0, void 0, function* () {
16858
- var _a, e_2, _b, _c;
16859
- let finalString = "";
16860
- try {
16861
- for (var _d = true, _e = __asyncValues(this), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
16862
- _c = _f.value;
16863
- _d = false;
16864
- const chunk = _c;
16865
- finalString += chunk;
17177
+ switch (packet.value.case) {
17178
+ case "streamHeader":
17179
+ return this.handleStreamHeader(packet.value.value, packet.participantIdentity);
17180
+ case "streamChunk":
17181
+ return this.handleStreamChunk(packet.value.value);
17182
+ case "streamTrailer":
17183
+ return this.handleStreamTrailer(packet.value.value);
17184
+ default:
17185
+ throw new Error('DataPacket of value "'.concat(packet.value.case, '" is not data stream related!'));
17186
+ }
17187
+ });
17188
+ }
17189
+ handleStreamHeader(streamHeader, participantIdentity) {
17190
+ return __awaiter(this, void 0, void 0, function* () {
17191
+ var _a;
17192
+ if (streamHeader.contentHeader.case === "byteHeader") {
17193
+ const streamHandlerCallback = this.byteStreamHandlers.get(streamHeader.topic);
17194
+ if (!streamHandlerCallback) {
17195
+ this.log.debug("ignoring incoming byte stream due to no handler for topic", streamHeader.topic);
17196
+ return;
16866
17197
  }
16867
- } catch (e_2_1) {
16868
- e_2 = {
16869
- error: e_2_1
17198
+ let streamController;
17199
+ const outOfBandFailureRejectingFuture = new Future();
17200
+ const info = {
17201
+ id: streamHeader.streamId,
17202
+ name: (_a = streamHeader.contentHeader.value.name) !== null && _a !== void 0 ? _a : "unknown",
17203
+ mimeType: streamHeader.mimeType,
17204
+ size: streamHeader.totalLength ? Number(streamHeader.totalLength) : void 0,
17205
+ topic: streamHeader.topic,
17206
+ timestamp: bigIntToNumber(streamHeader.timestamp),
17207
+ attributes: streamHeader.attributes
16870
17208
  };
16871
- } finally {
16872
- try {
16873
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
16874
- } finally {
16875
- if (e_2) throw e_2.error;
17209
+ const stream = new ReadableStream({
17210
+ start: (controller) => {
17211
+ streamController = controller;
17212
+ if (this.textStreamControllers.has(streamHeader.streamId)) {
17213
+ throw new DataStreamError("A data stream read is already in progress for a stream with id ".concat(streamHeader.streamId, "."), DataStreamErrorReason.AlreadyOpened);
17214
+ }
17215
+ this.byteStreamControllers.set(streamHeader.streamId, {
17216
+ info,
17217
+ controller: streamController,
17218
+ startTime: Date.now(),
17219
+ sendingParticipantIdentity: participantIdentity,
17220
+ outOfBandFailureRejectingFuture
17221
+ });
17222
+ }
17223
+ });
17224
+ streamHandlerCallback(new ByteStreamReader(info, stream, bigIntToNumber(streamHeader.totalLength), outOfBandFailureRejectingFuture), {
17225
+ identity: participantIdentity
17226
+ });
17227
+ } else if (streamHeader.contentHeader.case === "textHeader") {
17228
+ const streamHandlerCallback = this.textStreamHandlers.get(streamHeader.topic);
17229
+ if (!streamHandlerCallback) {
17230
+ this.log.debug("ignoring incoming text stream due to no handler for topic", streamHeader.topic);
17231
+ return;
16876
17232
  }
17233
+ let streamController;
17234
+ const outOfBandFailureRejectingFuture = new Future();
17235
+ const info = {
17236
+ id: streamHeader.streamId,
17237
+ mimeType: streamHeader.mimeType,
17238
+ size: streamHeader.totalLength ? Number(streamHeader.totalLength) : void 0,
17239
+ topic: streamHeader.topic,
17240
+ timestamp: Number(streamHeader.timestamp),
17241
+ attributes: streamHeader.attributes
17242
+ };
17243
+ const stream = new ReadableStream({
17244
+ start: (controller) => {
17245
+ streamController = controller;
17246
+ if (this.textStreamControllers.has(streamHeader.streamId)) {
17247
+ throw new DataStreamError("A data stream read is already in progress for a stream with id ".concat(streamHeader.streamId, "."), DataStreamErrorReason.AlreadyOpened);
17248
+ }
17249
+ this.textStreamControllers.set(streamHeader.streamId, {
17250
+ info,
17251
+ controller: streamController,
17252
+ startTime: Date.now(),
17253
+ sendingParticipantIdentity: participantIdentity,
17254
+ outOfBandFailureRejectingFuture
17255
+ });
17256
+ }
17257
+ });
17258
+ streamHandlerCallback(new TextStreamReader(info, stream, bigIntToNumber(streamHeader.totalLength), outOfBandFailureRejectingFuture), {
17259
+ identity: participantIdentity
17260
+ });
16877
17261
  }
16878
- return finalString;
16879
17262
  });
16880
17263
  }
17264
+ handleStreamChunk(chunk) {
17265
+ const fileBuffer = this.byteStreamControllers.get(chunk.streamId);
17266
+ if (fileBuffer) {
17267
+ if (chunk.content.length > 0) {
17268
+ fileBuffer.controller.enqueue(chunk);
17269
+ }
17270
+ }
17271
+ const textBuffer = this.textStreamControllers.get(chunk.streamId);
17272
+ if (textBuffer) {
17273
+ if (chunk.content.length > 0) {
17274
+ textBuffer.controller.enqueue(chunk);
17275
+ }
17276
+ }
17277
+ }
17278
+ handleStreamTrailer(trailer) {
17279
+ const textBuffer = this.textStreamControllers.get(trailer.streamId);
17280
+ if (textBuffer) {
17281
+ textBuffer.info.attributes = Object.assign(Object.assign({}, textBuffer.info.attributes), trailer.attributes);
17282
+ textBuffer.controller.close();
17283
+ this.textStreamControllers.delete(trailer.streamId);
17284
+ }
17285
+ const fileBuffer = this.byteStreamControllers.get(trailer.streamId);
17286
+ if (fileBuffer) {
17287
+ {
17288
+ fileBuffer.info.attributes = Object.assign(Object.assign({}, fileBuffer.info.attributes), trailer.attributes);
17289
+ fileBuffer.controller.close();
17290
+ this.byteStreamControllers.delete(trailer.streamId);
17291
+ }
17292
+ }
17293
+ }
16881
17294
  };
16882
17295
  BaseStreamWriter = class {
16883
17296
  constructor(writableStream, info, onClose) {
@@ -16902,6 +17315,277 @@ var init_livekit_client_esm = __esm({
16902
17315
  };
16903
17316
  ByteStreamWriter = class extends BaseStreamWriter {
16904
17317
  };
17318
+ STREAM_CHUNK_SIZE = 15e3;
17319
+ OutgoingDataStreamManager = class {
17320
+ constructor(engine, log2) {
17321
+ this.engine = engine;
17322
+ this.log = log2;
17323
+ }
17324
+ setupEngine(engine) {
17325
+ this.engine = engine;
17326
+ }
17327
+ /** {@inheritDoc LocalParticipant.sendText} */
17328
+ sendText(text7, options) {
17329
+ return __awaiter(this, void 0, void 0, function* () {
17330
+ var _a;
17331
+ const streamId = crypto.randomUUID();
17332
+ const textInBytes = new TextEncoder().encode(text7);
17333
+ const totalTextLength = textInBytes.byteLength;
17334
+ const fileIds = (_a = options === null || options === void 0 ? void 0 : options.attachments) === null || _a === void 0 ? void 0 : _a.map(() => crypto.randomUUID());
17335
+ const progresses = new Array(fileIds ? fileIds.length + 1 : 1).fill(0);
17336
+ const handleProgress = (progress, idx) => {
17337
+ var _a2;
17338
+ progresses[idx] = progress;
17339
+ const totalProgress = progresses.reduce((acc, val) => acc + val, 0);
17340
+ (_a2 = options === null || options === void 0 ? void 0 : options.onProgress) === null || _a2 === void 0 ? void 0 : _a2.call(options, totalProgress);
17341
+ };
17342
+ const writer2 = yield this.streamText({
17343
+ streamId,
17344
+ totalSize: totalTextLength,
17345
+ destinationIdentities: options === null || options === void 0 ? void 0 : options.destinationIdentities,
17346
+ topic: options === null || options === void 0 ? void 0 : options.topic,
17347
+ attachedStreamIds: fileIds,
17348
+ attributes: options === null || options === void 0 ? void 0 : options.attributes
17349
+ });
17350
+ yield writer2.write(text7);
17351
+ handleProgress(1, 0);
17352
+ yield writer2.close();
17353
+ if ((options === null || options === void 0 ? void 0 : options.attachments) && fileIds) {
17354
+ yield Promise.all(options.attachments.map((file, idx) => __awaiter(this, void 0, void 0, function* () {
17355
+ return this._sendFile(fileIds[idx], file, {
17356
+ topic: options.topic,
17357
+ mimeType: file.type,
17358
+ onProgress: (progress) => {
17359
+ handleProgress(progress, idx + 1);
17360
+ }
17361
+ });
17362
+ })));
17363
+ }
17364
+ return writer2.info;
17365
+ });
17366
+ }
17367
+ /**
17368
+ * @internal
17369
+ * @experimental CAUTION, might get removed in a minor release
17370
+ */
17371
+ streamText(options) {
17372
+ return __awaiter(this, void 0, void 0, function* () {
17373
+ var _a, _b;
17374
+ const streamId = (_a = options === null || options === void 0 ? void 0 : options.streamId) !== null && _a !== void 0 ? _a : crypto.randomUUID();
17375
+ const info = {
17376
+ id: streamId,
17377
+ mimeType: "text/plain",
17378
+ timestamp: Date.now(),
17379
+ topic: (_b = options === null || options === void 0 ? void 0 : options.topic) !== null && _b !== void 0 ? _b : "",
17380
+ size: options === null || options === void 0 ? void 0 : options.totalSize,
17381
+ attributes: options === null || options === void 0 ? void 0 : options.attributes
17382
+ };
17383
+ const header = new DataStream_Header({
17384
+ streamId,
17385
+ mimeType: info.mimeType,
17386
+ topic: info.topic,
17387
+ timestamp: numberToBigInt(info.timestamp),
17388
+ totalLength: numberToBigInt(options === null || options === void 0 ? void 0 : options.totalSize),
17389
+ attributes: info.attributes,
17390
+ contentHeader: {
17391
+ case: "textHeader",
17392
+ value: new DataStream_TextHeader({
17393
+ version: options === null || options === void 0 ? void 0 : options.version,
17394
+ attachedStreamIds: options === null || options === void 0 ? void 0 : options.attachedStreamIds,
17395
+ replyToStreamId: options === null || options === void 0 ? void 0 : options.replyToStreamId,
17396
+ operationType: (options === null || options === void 0 ? void 0 : options.type) === "update" ? DataStream_OperationType.UPDATE : DataStream_OperationType.CREATE
17397
+ })
17398
+ }
17399
+ });
17400
+ const destinationIdentities = options === null || options === void 0 ? void 0 : options.destinationIdentities;
17401
+ const packet = new DataPacket({
17402
+ destinationIdentities,
17403
+ value: {
17404
+ case: "streamHeader",
17405
+ value: header
17406
+ }
17407
+ });
17408
+ yield this.engine.sendDataPacket(packet, DataPacket_Kind.RELIABLE);
17409
+ let chunkId = 0;
17410
+ const engine = this.engine;
17411
+ const writableStream = new WritableStream({
17412
+ // Implement the sink
17413
+ write(text7) {
17414
+ return __awaiter(this, void 0, void 0, function* () {
17415
+ for (const textByteChunk of splitUtf8(text7, STREAM_CHUNK_SIZE)) {
17416
+ yield engine.waitForBufferStatusLow(DataPacket_Kind.RELIABLE);
17417
+ const chunk = new DataStream_Chunk({
17418
+ content: textByteChunk,
17419
+ streamId,
17420
+ chunkIndex: numberToBigInt(chunkId)
17421
+ });
17422
+ const chunkPacket = new DataPacket({
17423
+ destinationIdentities,
17424
+ value: {
17425
+ case: "streamChunk",
17426
+ value: chunk
17427
+ }
17428
+ });
17429
+ yield engine.sendDataPacket(chunkPacket, DataPacket_Kind.RELIABLE);
17430
+ chunkId += 1;
17431
+ }
17432
+ });
17433
+ },
17434
+ close() {
17435
+ return __awaiter(this, void 0, void 0, function* () {
17436
+ const trailer = new DataStream_Trailer({
17437
+ streamId
17438
+ });
17439
+ const trailerPacket = new DataPacket({
17440
+ destinationIdentities,
17441
+ value: {
17442
+ case: "streamTrailer",
17443
+ value: trailer
17444
+ }
17445
+ });
17446
+ yield engine.sendDataPacket(trailerPacket, DataPacket_Kind.RELIABLE);
17447
+ });
17448
+ },
17449
+ abort(err) {
17450
+ console.log("Sink error:", err);
17451
+ }
17452
+ });
17453
+ let onEngineClose = () => __awaiter(this, void 0, void 0, function* () {
17454
+ yield writer2.close();
17455
+ });
17456
+ engine.once(EngineEvent.Closing, onEngineClose);
17457
+ const writer2 = new TextStreamWriter(writableStream, info, () => this.engine.off(EngineEvent.Closing, onEngineClose));
17458
+ return writer2;
17459
+ });
17460
+ }
17461
+ sendFile(file, options) {
17462
+ return __awaiter(this, void 0, void 0, function* () {
17463
+ const streamId = crypto.randomUUID();
17464
+ yield this._sendFile(streamId, file, options);
17465
+ return {
17466
+ id: streamId
17467
+ };
17468
+ });
17469
+ }
17470
+ _sendFile(streamId, file, options) {
17471
+ return __awaiter(this, void 0, void 0, function* () {
17472
+ var _a;
17473
+ const writer2 = yield this.streamBytes({
17474
+ streamId,
17475
+ totalSize: file.size,
17476
+ name: file.name,
17477
+ mimeType: (_a = options === null || options === void 0 ? void 0 : options.mimeType) !== null && _a !== void 0 ? _a : file.type,
17478
+ topic: options === null || options === void 0 ? void 0 : options.topic,
17479
+ destinationIdentities: options === null || options === void 0 ? void 0 : options.destinationIdentities
17480
+ });
17481
+ const reader = file.stream().getReader();
17482
+ while (true) {
17483
+ const {
17484
+ done,
17485
+ value
17486
+ } = yield reader.read();
17487
+ if (done) {
17488
+ break;
17489
+ }
17490
+ yield writer2.write(value);
17491
+ }
17492
+ yield writer2.close();
17493
+ return writer2.info;
17494
+ });
17495
+ }
17496
+ streamBytes(options) {
17497
+ return __awaiter(this, void 0, void 0, function* () {
17498
+ var _a, _b, _c, _d, _e;
17499
+ const streamId = (_a = options === null || options === void 0 ? void 0 : options.streamId) !== null && _a !== void 0 ? _a : crypto.randomUUID();
17500
+ const destinationIdentities = options === null || options === void 0 ? void 0 : options.destinationIdentities;
17501
+ const info = {
17502
+ id: streamId,
17503
+ mimeType: (_b = options === null || options === void 0 ? void 0 : options.mimeType) !== null && _b !== void 0 ? _b : "application/octet-stream",
17504
+ topic: (_c = options === null || options === void 0 ? void 0 : options.topic) !== null && _c !== void 0 ? _c : "",
17505
+ timestamp: Date.now(),
17506
+ attributes: options === null || options === void 0 ? void 0 : options.attributes,
17507
+ size: options === null || options === void 0 ? void 0 : options.totalSize,
17508
+ name: (_d = options === null || options === void 0 ? void 0 : options.name) !== null && _d !== void 0 ? _d : "unknown"
17509
+ };
17510
+ const header = new DataStream_Header({
17511
+ totalLength: numberToBigInt((_e = info.size) !== null && _e !== void 0 ? _e : 0),
17512
+ mimeType: info.mimeType,
17513
+ streamId,
17514
+ topic: info.topic,
17515
+ timestamp: numberToBigInt(Date.now()),
17516
+ attributes: info.attributes,
17517
+ contentHeader: {
17518
+ case: "byteHeader",
17519
+ value: new DataStream_ByteHeader({
17520
+ name: info.name
17521
+ })
17522
+ }
17523
+ });
17524
+ const packet = new DataPacket({
17525
+ destinationIdentities,
17526
+ value: {
17527
+ case: "streamHeader",
17528
+ value: header
17529
+ }
17530
+ });
17531
+ yield this.engine.sendDataPacket(packet, DataPacket_Kind.RELIABLE);
17532
+ let chunkId = 0;
17533
+ const writeMutex = new _();
17534
+ const engine = this.engine;
17535
+ const logLocal = this.log;
17536
+ const writableStream = new WritableStream({
17537
+ write(chunk) {
17538
+ return __awaiter(this, void 0, void 0, function* () {
17539
+ const unlock = yield writeMutex.lock();
17540
+ let byteOffset = 0;
17541
+ try {
17542
+ while (byteOffset < chunk.byteLength) {
17543
+ const subChunk = chunk.slice(byteOffset, byteOffset + STREAM_CHUNK_SIZE);
17544
+ yield engine.waitForBufferStatusLow(DataPacket_Kind.RELIABLE);
17545
+ const chunkPacket = new DataPacket({
17546
+ destinationIdentities,
17547
+ value: {
17548
+ case: "streamChunk",
17549
+ value: new DataStream_Chunk({
17550
+ content: subChunk,
17551
+ streamId,
17552
+ chunkIndex: numberToBigInt(chunkId)
17553
+ })
17554
+ }
17555
+ });
17556
+ yield engine.sendDataPacket(chunkPacket, DataPacket_Kind.RELIABLE);
17557
+ chunkId += 1;
17558
+ byteOffset += subChunk.byteLength;
17559
+ }
17560
+ } finally {
17561
+ unlock();
17562
+ }
17563
+ });
17564
+ },
17565
+ close() {
17566
+ return __awaiter(this, void 0, void 0, function* () {
17567
+ const trailer = new DataStream_Trailer({
17568
+ streamId
17569
+ });
17570
+ const trailerPacket = new DataPacket({
17571
+ destinationIdentities,
17572
+ value: {
17573
+ case: "streamTrailer",
17574
+ value: trailer
17575
+ }
17576
+ });
17577
+ yield engine.sendDataPacket(trailerPacket, DataPacket_Kind.RELIABLE);
17578
+ });
17579
+ },
17580
+ abort(err) {
17581
+ logLocal.error("Sink error:", err);
17582
+ }
17583
+ });
17584
+ const byteWriter = new ByteStreamWriter(writableStream, info);
17585
+ return byteWriter;
17586
+ });
17587
+ }
17588
+ };
16905
17589
  RemoteTrack = class extends Track {
16906
17590
  constructor(mediaTrack, sid, kind, receiver, loggerOptions) {
16907
17591
  super(mediaTrack, kind, loggerOptions);
@@ -17237,6 +17921,13 @@ var init_livekit_client_esm = __esm({
17237
17921
  get isAdaptiveStream() {
17238
17922
  return this.adaptiveStreamSettings !== void 0;
17239
17923
  }
17924
+ setStreamState(value) {
17925
+ super.setStreamState(value);
17926
+ console.log("setStreamState", value);
17927
+ if (value === Track.StreamState.Active) {
17928
+ this.updateVisibility();
17929
+ }
17930
+ }
17240
17931
  /**
17241
17932
  * Note: When using adaptiveStream, you need to use remoteVideoTrack.attach() to add the track to a HTMLVideoElement, otherwise your video tracks might never start
17242
17933
  */
@@ -17380,13 +18071,13 @@ var init_livekit_client_esm = __esm({
17380
18071
  this.updateVisibility();
17381
18072
  });
17382
18073
  }
17383
- updateVisibility() {
18074
+ updateVisibility(forceEmit) {
17384
18075
  var _a, _b;
17385
18076
  const lastVisibilityChange = this.elementInfos.reduce((prev, info) => Math.max(prev, info.visibilityChangedAt || 0), 0);
17386
18077
  const backgroundPause = ((_b = (_a = this.adaptiveStreamSettings) === null || _a === void 0 ? void 0 : _a.pauseVideoInBackground) !== null && _b !== void 0 ? _b : true) ? this.isInBackground : false;
17387
18078
  const isPiPMode = this.elementInfos.some((info) => info.pictureInPicture);
17388
18079
  const isVisible = this.elementInfos.some((info) => info.visible) && !backgroundPause || isPiPMode;
17389
- if (this.lastVisible === isVisible) {
18080
+ if (this.lastVisible === isVisible && !forceEmit) {
17390
18081
  return;
17391
18082
  }
17392
18083
  if (!isVisible && Date.now() - lastVisibilityChange < REACTION_DELAY) {
@@ -17954,10 +18645,9 @@ var init_livekit_client_esm = __esm({
17954
18645
  }
17955
18646
  }
17956
18647
  };
17957
- STREAM_CHUNK_SIZE = 15e3;
17958
18648
  LocalParticipant = class extends Participant {
17959
18649
  /** @internal */
17960
- constructor(sid, identity, engine, options, roomRpcHandlers) {
18650
+ constructor(sid, identity, engine, options, roomRpcHandlers, roomOutgoingDataStreamManager) {
17961
18651
  super(sid, identity, void 0, void 0, void 0, {
17962
18652
  loggerName: options.loggerName,
17963
18653
  loggerContextCb: () => this.engine.logContext
@@ -18183,6 +18873,7 @@ var init_livekit_client_esm = __esm({
18183
18873
  this.activeDeviceMap = /* @__PURE__ */ new Map([["audioinput", "default"], ["videoinput", "default"], ["audiooutput", "default"]]);
18184
18874
  this.pendingSignalRequests = /* @__PURE__ */ new Map();
18185
18875
  this.rpcHandlers = roomRpcHandlers;
18876
+ this.roomOutgoingDataStreamManager = roomOutgoingDataStreamManager;
18186
18877
  }
18187
18878
  get lastCameraError() {
18188
18879
  return this.cameraError;
@@ -18274,7 +18965,7 @@ var init_livekit_client_esm = __esm({
18274
18965
  name: name2,
18275
18966
  attributes
18276
18967
  } = _ref;
18277
- return function* () {
18968
+ return (function* () {
18278
18969
  return new Promise((resolve, reject) => __awaiter(_this, void 0, void 0, function* () {
18279
18970
  var _a2, _b;
18280
18971
  try {
@@ -18309,7 +19000,7 @@ var init_livekit_client_esm = __esm({
18309
19000
  if (e3 instanceof Error) reject(e3);
18310
19001
  }
18311
19002
  }));
18312
- }();
19003
+ })();
18313
19004
  });
18314
19005
  }
18315
19006
  /**
@@ -18578,7 +19269,7 @@ var init_livekit_client_esm = __esm({
18578
19269
  return __awaiter(this, arguments, void 0, function(track, options) {
18579
19270
  var _this2 = this;
18580
19271
  let isRepublish = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : false;
18581
- return function* () {
19272
+ return (function* () {
18582
19273
  var _a, _b, _c, _d;
18583
19274
  if (isLocalAudioTrack(track)) {
18584
19275
  track.setAudioContext(_this2.audioContext);
@@ -18703,7 +19394,7 @@ var init_livekit_client_esm = __esm({
18703
19394
  } finally {
18704
19395
  _this2.pendingPublishPromises.delete(track);
18705
19396
  }
18706
- }();
19397
+ })();
18707
19398
  });
18708
19399
  }
18709
19400
  waitUntilEngineConnected() {
@@ -19185,7 +19876,7 @@ var init_livekit_client_esm = __esm({
19185
19876
  return __awaiter(this, arguments, void 0, function(options) {
19186
19877
  var _this3 = this;
19187
19878
  let restartTracks = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true;
19188
- return function* () {
19879
+ return (function* () {
19189
19880
  if (_this3.republishPromise) {
19190
19881
  yield _this3.republishPromise;
19191
19882
  }
@@ -19219,7 +19910,7 @@ var init_livekit_client_esm = __esm({
19219
19910
  }
19220
19911
  }));
19221
19912
  yield _this3.republishPromise;
19222
- }();
19913
+ })();
19223
19914
  });
19224
19915
  }
19225
19916
  /**
@@ -19233,7 +19924,7 @@ var init_livekit_client_esm = __esm({
19233
19924
  return __awaiter(this, arguments, void 0, function(data) {
19234
19925
  var _this4 = this;
19235
19926
  let options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
19236
- return function* () {
19927
+ return (function* () {
19237
19928
  const kind = options.reliable ? DataPacket_Kind.RELIABLE : DataPacket_Kind.LOSSY;
19238
19929
  const destinationIdentities = options.destinationIdentities;
19239
19930
  const topic = options.topic;
@@ -19250,7 +19941,7 @@ var init_livekit_client_esm = __esm({
19250
19941
  }
19251
19942
  });
19252
19943
  yield _this4.engine.sendDataPacket(packet, kind);
19253
- }();
19944
+ })();
19254
19945
  });
19255
19946
  }
19256
19947
  /**
@@ -19274,6 +19965,7 @@ var init_livekit_client_esm = __esm({
19274
19965
  yield this.engine.sendDataPacket(packet, DataPacket_Kind.RELIABLE);
19275
19966
  });
19276
19967
  }
19968
+ /** @deprecated Consider migrating to {@link sendText} */
19277
19969
  sendChatMessage(text7, options) {
19278
19970
  return __awaiter(this, void 0, void 0, function* () {
19279
19971
  const msg = {
@@ -19295,6 +19987,7 @@ var init_livekit_client_esm = __esm({
19295
19987
  return msg;
19296
19988
  });
19297
19989
  }
19990
+ /** @deprecated Consider migrating to {@link sendText} */
19298
19991
  editChatMessage(editText, originalMessage) {
19299
19992
  return __awaiter(this, void 0, void 0, function* () {
19300
19993
  const msg = Object.assign(Object.assign({}, originalMessage), {
@@ -19315,264 +20008,51 @@ var init_livekit_client_esm = __esm({
19315
20008
  return msg;
19316
20009
  });
19317
20010
  }
20011
+ /**
20012
+ * Sends the given string to participants in the room via the data channel.
20013
+ * For longer messages, consider using {@link streamText} instead.
20014
+ *
20015
+ * @param text The text payload
20016
+ * @param options.topic Topic identifier used to route the stream to appropriate handlers.
20017
+ */
19318
20018
  sendText(text7, options) {
19319
20019
  return __awaiter(this, void 0, void 0, function* () {
19320
- var _a;
19321
- const streamId = crypto.randomUUID();
19322
- const textInBytes = new TextEncoder().encode(text7);
19323
- const totalTextLength = textInBytes.byteLength;
19324
- const fileIds = (_a = options === null || options === void 0 ? void 0 : options.attachments) === null || _a === void 0 ? void 0 : _a.map(() => crypto.randomUUID());
19325
- const progresses = new Array(fileIds ? fileIds.length + 1 : 1).fill(0);
19326
- const handleProgress = (progress, idx) => {
19327
- var _a2;
19328
- progresses[idx] = progress;
19329
- const totalProgress = progresses.reduce((acc, val) => acc + val, 0);
19330
- (_a2 = options === null || options === void 0 ? void 0 : options.onProgress) === null || _a2 === void 0 ? void 0 : _a2.call(options, totalProgress);
19331
- };
19332
- const writer2 = yield this.streamText({
19333
- streamId,
19334
- totalSize: totalTextLength,
19335
- destinationIdentities: options === null || options === void 0 ? void 0 : options.destinationIdentities,
19336
- topic: options === null || options === void 0 ? void 0 : options.topic,
19337
- attachedStreamIds: fileIds,
19338
- attributes: options === null || options === void 0 ? void 0 : options.attributes
19339
- });
19340
- yield writer2.write(text7);
19341
- handleProgress(1, 0);
19342
- yield writer2.close();
19343
- if ((options === null || options === void 0 ? void 0 : options.attachments) && fileIds) {
19344
- yield Promise.all(options.attachments.map((file, idx) => __awaiter(this, void 0, void 0, function* () {
19345
- return this._sendFile(fileIds[idx], file, {
19346
- topic: options.topic,
19347
- mimeType: file.type,
19348
- onProgress: (progress) => {
19349
- handleProgress(progress, idx + 1);
19350
- }
19351
- });
19352
- })));
19353
- }
19354
- return writer2.info;
20020
+ return this.roomOutgoingDataStreamManager.sendText(text7, options);
19355
20021
  });
19356
20022
  }
19357
20023
  /**
20024
+ * Creates a new TextStreamWriter which can be used to stream text incrementally
20025
+ * to participants in the room via the data channel.
20026
+ *
20027
+ * @param options.topic Topic identifier used to route the stream to appropriate handlers.
20028
+ *
19358
20029
  * @internal
19359
20030
  * @experimental CAUTION, might get removed in a minor release
19360
20031
  */
19361
20032
  streamText(options) {
19362
20033
  return __awaiter(this, void 0, void 0, function* () {
19363
- var _a, _b;
19364
- const streamId = (_a = options === null || options === void 0 ? void 0 : options.streamId) !== null && _a !== void 0 ? _a : crypto.randomUUID();
19365
- const info = {
19366
- id: streamId,
19367
- mimeType: "text/plain",
19368
- timestamp: Date.now(),
19369
- topic: (_b = options === null || options === void 0 ? void 0 : options.topic) !== null && _b !== void 0 ? _b : "",
19370
- size: options === null || options === void 0 ? void 0 : options.totalSize,
19371
- attributes: options === null || options === void 0 ? void 0 : options.attributes
19372
- };
19373
- const header = new DataStream_Header({
19374
- streamId,
19375
- mimeType: info.mimeType,
19376
- topic: info.topic,
19377
- timestamp: numberToBigInt(info.timestamp),
19378
- totalLength: numberToBigInt(options === null || options === void 0 ? void 0 : options.totalSize),
19379
- attributes: info.attributes,
19380
- contentHeader: {
19381
- case: "textHeader",
19382
- value: new DataStream_TextHeader({
19383
- version: options === null || options === void 0 ? void 0 : options.version,
19384
- attachedStreamIds: options === null || options === void 0 ? void 0 : options.attachedStreamIds,
19385
- replyToStreamId: options === null || options === void 0 ? void 0 : options.replyToStreamId,
19386
- operationType: (options === null || options === void 0 ? void 0 : options.type) === "update" ? DataStream_OperationType.UPDATE : DataStream_OperationType.CREATE
19387
- })
19388
- }
19389
- });
19390
- const destinationIdentities = options === null || options === void 0 ? void 0 : options.destinationIdentities;
19391
- const packet = new DataPacket({
19392
- destinationIdentities,
19393
- value: {
19394
- case: "streamHeader",
19395
- value: header
19396
- }
19397
- });
19398
- yield this.engine.sendDataPacket(packet, DataPacket_Kind.RELIABLE);
19399
- let chunkId = 0;
19400
- const localP = this;
19401
- const writableStream = new WritableStream({
19402
- // Implement the sink
19403
- write(text7) {
19404
- return __awaiter(this, void 0, void 0, function* () {
19405
- for (const textByteChunk of splitUtf8(text7, STREAM_CHUNK_SIZE)) {
19406
- yield localP.engine.waitForBufferStatusLow(DataPacket_Kind.RELIABLE);
19407
- const chunk = new DataStream_Chunk({
19408
- content: textByteChunk,
19409
- streamId,
19410
- chunkIndex: numberToBigInt(chunkId)
19411
- });
19412
- const chunkPacket = new DataPacket({
19413
- destinationIdentities,
19414
- value: {
19415
- case: "streamChunk",
19416
- value: chunk
19417
- }
19418
- });
19419
- yield localP.engine.sendDataPacket(chunkPacket, DataPacket_Kind.RELIABLE);
19420
- chunkId += 1;
19421
- }
19422
- });
19423
- },
19424
- close() {
19425
- return __awaiter(this, void 0, void 0, function* () {
19426
- const trailer = new DataStream_Trailer({
19427
- streamId
19428
- });
19429
- const trailerPacket = new DataPacket({
19430
- destinationIdentities,
19431
- value: {
19432
- case: "streamTrailer",
19433
- value: trailer
19434
- }
19435
- });
19436
- yield localP.engine.sendDataPacket(trailerPacket, DataPacket_Kind.RELIABLE);
19437
- });
19438
- },
19439
- abort(err) {
19440
- console.log("Sink error:", err);
19441
- }
19442
- });
19443
- let onEngineClose = () => __awaiter(this, void 0, void 0, function* () {
19444
- yield writer2.close();
19445
- });
19446
- localP.engine.once(EngineEvent.Closing, onEngineClose);
19447
- const writer2 = new TextStreamWriter(writableStream, info, () => this.engine.off(EngineEvent.Closing, onEngineClose));
19448
- return writer2;
20034
+ return this.roomOutgoingDataStreamManager.streamText(options);
19449
20035
  });
19450
20036
  }
20037
+ /** Send a File to all participants in the room via the data channel.
20038
+ * @param file The File object payload
20039
+ * @param options.topic Topic identifier used to route the stream to appropriate handlers.
20040
+ * @param options.onProgress A callback function used to monitor the upload progress percentage.
20041
+ */
19451
20042
  sendFile(file, options) {
19452
20043
  return __awaiter(this, void 0, void 0, function* () {
19453
- const streamId = crypto.randomUUID();
19454
- yield this._sendFile(streamId, file, options);
19455
- return {
19456
- id: streamId
19457
- };
19458
- });
19459
- }
19460
- _sendFile(streamId, file, options) {
19461
- return __awaiter(this, void 0, void 0, function* () {
19462
- var _a;
19463
- const writer2 = yield this.streamBytes({
19464
- streamId,
19465
- totalSize: file.size,
19466
- name: file.name,
19467
- mimeType: (_a = options === null || options === void 0 ? void 0 : options.mimeType) !== null && _a !== void 0 ? _a : file.type,
19468
- topic: options === null || options === void 0 ? void 0 : options.topic,
19469
- destinationIdentities: options === null || options === void 0 ? void 0 : options.destinationIdentities
19470
- });
19471
- const reader = file.stream().getReader();
19472
- while (true) {
19473
- const {
19474
- done,
19475
- value
19476
- } = yield reader.read();
19477
- if (done) {
19478
- break;
19479
- }
19480
- yield writer2.write(value);
19481
- }
19482
- yield writer2.close();
19483
- return writer2.info;
20044
+ return this.roomOutgoingDataStreamManager.sendFile(file, options);
19484
20045
  });
19485
20046
  }
20047
+ /**
20048
+ * Stream bytes incrementally to participants in the room via the data channel.
20049
+ * For sending files, consider using {@link sendFile} instead.
20050
+ *
20051
+ * @param options.topic Topic identifier used to route the stream to appropriate handlers.
20052
+ */
19486
20053
  streamBytes(options) {
19487
20054
  return __awaiter(this, void 0, void 0, function* () {
19488
- var _a, _b, _c, _d, _e;
19489
- const streamId = (_a = options === null || options === void 0 ? void 0 : options.streamId) !== null && _a !== void 0 ? _a : crypto.randomUUID();
19490
- const destinationIdentities = options === null || options === void 0 ? void 0 : options.destinationIdentities;
19491
- const info = {
19492
- id: streamId,
19493
- mimeType: (_b = options === null || options === void 0 ? void 0 : options.mimeType) !== null && _b !== void 0 ? _b : "application/octet-stream",
19494
- topic: (_c = options === null || options === void 0 ? void 0 : options.topic) !== null && _c !== void 0 ? _c : "",
19495
- timestamp: Date.now(),
19496
- attributes: options === null || options === void 0 ? void 0 : options.attributes,
19497
- size: options === null || options === void 0 ? void 0 : options.totalSize,
19498
- name: (_d = options === null || options === void 0 ? void 0 : options.name) !== null && _d !== void 0 ? _d : "unknown"
19499
- };
19500
- const header = new DataStream_Header({
19501
- totalLength: numberToBigInt((_e = info.size) !== null && _e !== void 0 ? _e : 0),
19502
- mimeType: info.mimeType,
19503
- streamId,
19504
- topic: info.topic,
19505
- timestamp: numberToBigInt(Date.now()),
19506
- attributes: info.attributes,
19507
- contentHeader: {
19508
- case: "byteHeader",
19509
- value: new DataStream_ByteHeader({
19510
- name: info.name
19511
- })
19512
- }
19513
- });
19514
- const packet = new DataPacket({
19515
- destinationIdentities,
19516
- value: {
19517
- case: "streamHeader",
19518
- value: header
19519
- }
19520
- });
19521
- yield this.engine.sendDataPacket(packet, DataPacket_Kind.RELIABLE);
19522
- let chunkId = 0;
19523
- const writeMutex = new _();
19524
- const engine = this.engine;
19525
- const log2 = this.log;
19526
- const writableStream = new WritableStream({
19527
- write(chunk) {
19528
- return __awaiter(this, void 0, void 0, function* () {
19529
- const unlock = yield writeMutex.lock();
19530
- let byteOffset = 0;
19531
- try {
19532
- while (byteOffset < chunk.byteLength) {
19533
- const subChunk = chunk.slice(byteOffset, byteOffset + STREAM_CHUNK_SIZE);
19534
- yield engine.waitForBufferStatusLow(DataPacket_Kind.RELIABLE);
19535
- const chunkPacket = new DataPacket({
19536
- destinationIdentities,
19537
- value: {
19538
- case: "streamChunk",
19539
- value: new DataStream_Chunk({
19540
- content: subChunk,
19541
- streamId,
19542
- chunkIndex: numberToBigInt(chunkId)
19543
- })
19544
- }
19545
- });
19546
- yield engine.sendDataPacket(chunkPacket, DataPacket_Kind.RELIABLE);
19547
- chunkId += 1;
19548
- byteOffset += subChunk.byteLength;
19549
- }
19550
- } finally {
19551
- unlock();
19552
- }
19553
- });
19554
- },
19555
- close() {
19556
- return __awaiter(this, void 0, void 0, function* () {
19557
- const trailer = new DataStream_Trailer({
19558
- streamId
19559
- });
19560
- const trailerPacket = new DataPacket({
19561
- destinationIdentities,
19562
- value: {
19563
- case: "streamTrailer",
19564
- value: trailer
19565
- }
19566
- });
19567
- yield engine.sendDataPacket(trailerPacket, DataPacket_Kind.RELIABLE);
19568
- });
19569
- },
19570
- abort(err) {
19571
- log2.error("Sink error:", err);
19572
- }
19573
- });
19574
- const byteWriter = new ByteStreamWriter(writableStream, info);
19575
- return byteWriter;
20055
+ return this.roomOutgoingDataStreamManager.streamBytes(options);
19576
20056
  });
19577
20057
  }
19578
20058
  /**
@@ -19590,7 +20070,7 @@ var init_livekit_client_esm = __esm({
19590
20070
  payload,
19591
20071
  responseTimeout = 1e4
19592
20072
  } = _ref3;
19593
- return function* () {
20073
+ return (function* () {
19594
20074
  const maxRoundTripLatency = 2e3;
19595
20075
  return new Promise((resolve, reject) => __awaiter(_this5, void 0, void 0, function* () {
19596
20076
  var _a2, _b, _c, _d;
@@ -19637,7 +20117,7 @@ var init_livekit_client_esm = __esm({
19637
20117
  participantIdentity: destinationIdentity
19638
20118
  });
19639
20119
  }));
19640
- }();
20120
+ })();
19641
20121
  });
19642
20122
  }
19643
20123
  /**
@@ -20329,12 +20809,12 @@ var init_livekit_client_esm = __esm({
20329
20809
  return super.emit(event, ...args);
20330
20810
  }
20331
20811
  };
20332
- (function(ConnectionState2) {
20333
- ConnectionState2["Disconnected"] = "disconnected";
20334
- ConnectionState2["Connecting"] = "connecting";
20335
- ConnectionState2["Connected"] = "connected";
20336
- ConnectionState2["Reconnecting"] = "reconnecting";
20337
- ConnectionState2["SignalReconnecting"] = "signalReconnecting";
20812
+ (function(ConnectionState3) {
20813
+ ConnectionState3["Disconnected"] = "disconnected";
20814
+ ConnectionState3["Connecting"] = "connecting";
20815
+ ConnectionState3["Connected"] = "connected";
20816
+ ConnectionState3["Reconnecting"] = "reconnecting";
20817
+ ConnectionState3["SignalReconnecting"] = "signalReconnecting";
20338
20818
  })(ConnectionState || (ConnectionState = {}));
20339
20819
  connectionReconcileFrequency = 4 * 1e3;
20340
20820
  Room = class _Room extends eventsExports.EventEmitter {
@@ -20355,10 +20835,6 @@ var init_livekit_client_esm = __esm({
20355
20835
  this.log = livekitLogger;
20356
20836
  this.bufferedEvents = [];
20357
20837
  this.isResuming = false;
20358
- this.byteStreamControllers = /* @__PURE__ */ new Map();
20359
- this.textStreamControllers = /* @__PURE__ */ new Map();
20360
- this.byteStreamHandlers = /* @__PURE__ */ new Map();
20361
- this.textStreamHandlers = /* @__PURE__ */ new Map();
20362
20838
  this.rpcHandlers = /* @__PURE__ */ new Map();
20363
20839
  this.connect = (url, token2, opts) => __awaiter(this, void 0, void 0, function* () {
20364
20840
  var _a2;
@@ -20573,7 +21049,7 @@ var init_livekit_client_esm = __esm({
20573
21049
  return __awaiter(_this, [...args_1], void 0, function() {
20574
21050
  var _this2 = this;
20575
21051
  let stopTracks = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : true;
20576
- return function* () {
21052
+ return (function* () {
20577
21053
  var _a2, _b2, _c2, _d;
20578
21054
  const unlock = yield _this2.disconnectLock.lock();
20579
21055
  try {
@@ -20599,7 +21075,7 @@ var init_livekit_client_esm = __esm({
20599
21075
  } finally {
20600
21076
  unlock();
20601
21077
  }
20602
- }();
21078
+ })();
20603
21079
  });
20604
21080
  };
20605
21081
  this.onPageLeave = () => __awaiter(this, void 0, void 0, function* () {
@@ -20807,8 +21283,8 @@ var init_livekit_client_esm = __esm({
20807
21283
  return;
20808
21284
  }
20809
21285
  const newStreamState = Track.streamStateFromProto(streamState.state);
21286
+ pub.track.setStreamState(newStreamState);
20810
21287
  if (newStreamState !== pub.track.streamState) {
20811
- pub.track.streamState = newStreamState;
20812
21288
  participant.emit(ParticipantEvent.TrackStreamStateChanged, pub, pub.track.streamState);
20813
21289
  this.emitWhenConnected(RoomEvent.TrackStreamStateChanged, pub, pub.track.streamState, participant);
20814
21290
  }
@@ -20848,12 +21324,8 @@ var init_livekit_client_esm = __esm({
20848
21324
  this.handleChatMessage(participant, packet.value.value);
20849
21325
  } else if (packet.value.case === "metrics") {
20850
21326
  this.handleMetrics(packet.value.value, participant);
20851
- } else if (packet.value.case === "streamHeader") {
20852
- this.handleStreamHeader(packet.value.value, packet.participantIdentity);
20853
- } else if (packet.value.case === "streamChunk") {
20854
- this.handleStreamChunk(packet.value.value);
20855
- } else if (packet.value.case === "streamTrailer") {
20856
- this.handleStreamTrailer(packet.value.value);
21327
+ } else if (packet.value.case === "streamHeader" || packet.value.case === "streamChunk" || packet.value.case === "streamTrailer") {
21328
+ this.handleDataStream(packet);
20857
21329
  } else if (packet.value.case === "rpcRequest") {
20858
21330
  const rpc = packet.value.value;
20859
21331
  this.handleIncomingRpcRequest(packet.participantIdentity, rpc.id, rpc.method, rpc.payload, rpc.responseTimeoutMs, rpc.version);
@@ -20867,7 +21339,6 @@ var init_livekit_client_esm = __esm({
20867
21339
  this.emit(RoomEvent.SipDTMFReceived, dtmf, participant);
20868
21340
  participant === null || participant === void 0 ? void 0 : participant.emit(ParticipantEvent.SipDTMFReceived, dtmf);
20869
21341
  };
20870
- this.bufferedSegments = /* @__PURE__ */ new Map();
20871
21342
  this.handleTranscription = (_remoteParticipant, transcription) => {
20872
21343
  const participant = transcription.transcribedParticipantIdentity === this.localParticipant.identity ? this.localParticipant : this.getParticipantByIdentity(transcription.transcribedParticipantIdentity);
20873
21344
  const publication = participant === null || participant === void 0 ? void 0 : participant.trackPublications.get(transcription.trackId);
@@ -20883,6 +21354,10 @@ var init_livekit_client_esm = __esm({
20883
21354
  this.handleMetrics = (metrics, participant) => {
20884
21355
  this.emit(RoomEvent.MetricsReceived, metrics, participant);
20885
21356
  };
21357
+ this.handleDataStream = (packet) => {
21358
+ this.incomingDataStreamManager.handleDataStreamPacket(packet);
21359
+ };
21360
+ this.bufferedSegments = /* @__PURE__ */ new Map();
20886
21361
  this.handleAudioPlaybackStarted = () => {
20887
21362
  if (this.canPlaybackAudio) {
20888
21363
  return;
@@ -21016,8 +21491,10 @@ var init_livekit_client_esm = __esm({
21016
21491
  this.options.videoCaptureDefaults = Object.assign(Object.assign({}, videoDefaults), options === null || options === void 0 ? void 0 : options.videoCaptureDefaults);
21017
21492
  this.options.publishDefaults = Object.assign(Object.assign({}, publishDefaults), options === null || options === void 0 ? void 0 : options.publishDefaults);
21018
21493
  this.maybeCreateEngine();
21494
+ this.incomingDataStreamManager = new IncomingDataStreamManager();
21495
+ this.outgoingDataStreamManager = new OutgoingDataStreamManager(this.engine, this.log);
21019
21496
  this.disconnectLock = new _();
21020
- this.localParticipant = new LocalParticipant("", "", this.engine, this.options, this.rpcHandlers);
21497
+ this.localParticipant = new LocalParticipant("", "", this.engine, this.options, this.rpcHandlers, this.outgoingDataStreamManager);
21021
21498
  if (this.options.videoCaptureDefaults.deviceId) {
21022
21499
  this.localParticipant.activeDeviceMap.set("videoinput", unwrapConstraint(this.options.videoCaptureDefaults.deviceId));
21023
21500
  }
@@ -21043,22 +21520,16 @@ var init_livekit_client_esm = __esm({
21043
21520
  }
21044
21521
  }
21045
21522
  registerTextStreamHandler(topic, callback) {
21046
- if (this.textStreamHandlers.has(topic)) {
21047
- throw new TypeError('A text stream handler for topic "'.concat(topic, '" has already been set.'));
21048
- }
21049
- this.textStreamHandlers.set(topic, callback);
21523
+ return this.incomingDataStreamManager.registerTextStreamHandler(topic, callback);
21050
21524
  }
21051
21525
  unregisterTextStreamHandler(topic) {
21052
- this.textStreamHandlers.delete(topic);
21526
+ return this.incomingDataStreamManager.unregisterTextStreamHandler(topic);
21053
21527
  }
21054
21528
  registerByteStreamHandler(topic, callback) {
21055
- if (this.byteStreamHandlers.has(topic)) {
21056
- throw new TypeError('A byte stream handler for topic "'.concat(topic, '" has already been set.'));
21057
- }
21058
- this.byteStreamHandlers.set(topic, callback);
21529
+ return this.incomingDataStreamManager.registerByteStreamHandler(topic, callback);
21059
21530
  }
21060
21531
  unregisterByteStreamHandler(topic) {
21061
- this.byteStreamHandlers.delete(topic);
21532
+ return this.incomingDataStreamManager.unregisterByteStreamHandler(topic);
21062
21533
  }
21063
21534
  /**
21064
21535
  * Establishes the participant as a receiver for calls of the specified RPC method.
@@ -21100,44 +21571,6 @@ var init_livekit_client_esm = __esm({
21100
21571
  unregisterRpcMethod(method) {
21101
21572
  this.rpcHandlers.delete(method);
21102
21573
  }
21103
- handleIncomingRpcRequest(callerIdentity, requestId, method, payload, responseTimeout, version2) {
21104
- return __awaiter(this, void 0, void 0, function* () {
21105
- yield this.engine.publishRpcAck(callerIdentity, requestId);
21106
- if (version2 !== 1) {
21107
- yield this.engine.publishRpcResponse(callerIdentity, requestId, null, RpcError.builtIn("UNSUPPORTED_VERSION"));
21108
- return;
21109
- }
21110
- const handler = this.rpcHandlers.get(method);
21111
- if (!handler) {
21112
- yield this.engine.publishRpcResponse(callerIdentity, requestId, null, RpcError.builtIn("UNSUPPORTED_METHOD"));
21113
- return;
21114
- }
21115
- let responseError = null;
21116
- let responsePayload = null;
21117
- try {
21118
- const response = yield handler({
21119
- requestId,
21120
- callerIdentity,
21121
- payload,
21122
- responseTimeout
21123
- });
21124
- if (byteLength(response) > MAX_PAYLOAD_BYTES) {
21125
- responseError = RpcError.builtIn("RESPONSE_PAYLOAD_TOO_LARGE");
21126
- console.warn("RPC Response payload too large for ".concat(method));
21127
- } else {
21128
- responsePayload = response;
21129
- }
21130
- } catch (error) {
21131
- if (error instanceof RpcError) {
21132
- responseError = error;
21133
- } else {
21134
- console.warn("Uncaught error returned by RPC handler for ".concat(method, ". Returning APPLICATION_ERROR instead."), error);
21135
- responseError = RpcError.builtIn("APPLICATION_ERROR");
21136
- }
21137
- }
21138
- yield this.engine.publishRpcResponse(callerIdentity, requestId, responsePayload, responseError);
21139
- });
21140
- }
21141
21574
  /**
21142
21575
  * @experimental
21143
21576
  */
@@ -21302,6 +21735,9 @@ var init_livekit_client_esm = __esm({
21302
21735
  if (this.e2eeManager) {
21303
21736
  this.e2eeManager.setupEngine(this.engine);
21304
21737
  }
21738
+ if (this.outgoingDataStreamManager) {
21739
+ this.outgoingDataStreamManager.setupEngine(this.engine);
21740
+ }
21305
21741
  }
21306
21742
  /**
21307
21743
  * getLocalDevices abstracts navigator.mediaDevices.enumerateDevices.
@@ -21512,7 +21948,7 @@ var init_livekit_client_esm = __esm({
21512
21948
  return __awaiter(this, arguments, void 0, function(kind, deviceId) {
21513
21949
  var _this3 = this;
21514
21950
  let exact = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : true;
21515
- return function* () {
21951
+ return (function* () {
21516
21952
  var _a, _b, _c, _d, _e, _f;
21517
21953
  var _g;
21518
21954
  let success = true;
@@ -21586,7 +22022,7 @@ var init_livekit_client_esm = __esm({
21586
22022
  _this3.emit(RoomEvent.ActiveDeviceChanged, kind, deviceId);
21587
22023
  }
21588
22024
  return success;
21589
- }();
22025
+ })();
21590
22026
  });
21591
22027
  }
21592
22028
  setupLocalParticipantEvents() {
@@ -21648,7 +22084,10 @@ var init_livekit_client_esm = __esm({
21648
22084
  adaptiveStreamSettings = {};
21649
22085
  }
21650
22086
  }
21651
- participant.addSubscribedMediaTrack(mediaTrack, trackId, stream, receiver, adaptiveStreamSettings);
22087
+ const publication = participant.addSubscribedMediaTrack(mediaTrack, trackId, stream, receiver, adaptiveStreamSettings);
22088
+ if ((publication === null || publication === void 0 ? void 0 : publication.isEncrypted) && !this.e2eeManager) {
22089
+ this.emit(RoomEvent.EncryptionError, new Error("Encrypted ".concat(publication.source, " track received from participant ").concat(participant.sid, ", but room does not have encryption enabled!")));
22090
+ }
21652
22091
  }
21653
22092
  handleDisconnect() {
21654
22093
  let shouldStopTracks = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : true;
@@ -21658,6 +22097,7 @@ var init_livekit_client_esm = __esm({
21658
22097
  this.isResuming = false;
21659
22098
  this.bufferedEvents = [];
21660
22099
  this.transcriptionReceivedTimes.clear();
22100
+ this.incomingDataStreamManager.clearHandlersAndControllers();
21661
22101
  if (this.state === ConnectionState.Disconnected) {
21662
22102
  return;
21663
22103
  }
@@ -21708,6 +22148,7 @@ var init_livekit_client_esm = __esm({
21708
22148
  if (!participant) {
21709
22149
  return;
21710
22150
  }
22151
+ this.incomingDataStreamManager.validateParticipantHasNoActiveDataStreams(identity);
21711
22152
  participant.trackPublications.forEach((publication) => {
21712
22153
  participant.unpublishTrack(publication.trackSid, true);
21713
22154
  });
@@ -21715,99 +22156,44 @@ var init_livekit_client_esm = __esm({
21715
22156
  participant.setDisconnected();
21716
22157
  (_a = this.localParticipant) === null || _a === void 0 ? void 0 : _a.handleParticipantDisconnected(participant.identity);
21717
22158
  }
21718
- handleStreamHeader(streamHeader, participantIdentity) {
22159
+ handleIncomingRpcRequest(callerIdentity, requestId, method, payload, responseTimeout, version2) {
21719
22160
  return __awaiter(this, void 0, void 0, function* () {
21720
- var _a;
21721
- if (streamHeader.contentHeader.case === "byteHeader") {
21722
- const streamHandlerCallback = this.byteStreamHandlers.get(streamHeader.topic);
21723
- if (!streamHandlerCallback) {
21724
- this.log.debug("ignoring incoming byte stream due to no handler for topic", streamHeader.topic);
21725
- return;
21726
- }
21727
- let streamController;
21728
- const info = {
21729
- id: streamHeader.streamId,
21730
- name: (_a = streamHeader.contentHeader.value.name) !== null && _a !== void 0 ? _a : "unknown",
21731
- mimeType: streamHeader.mimeType,
21732
- size: streamHeader.totalLength ? Number(streamHeader.totalLength) : void 0,
21733
- topic: streamHeader.topic,
21734
- timestamp: bigIntToNumber(streamHeader.timestamp),
21735
- attributes: streamHeader.attributes
21736
- };
21737
- const stream = new ReadableStream({
21738
- start: (controller) => {
21739
- streamController = controller;
21740
- this.byteStreamControllers.set(streamHeader.streamId, {
21741
- info,
21742
- controller: streamController,
21743
- startTime: Date.now()
21744
- });
21745
- }
21746
- });
21747
- streamHandlerCallback(new ByteStreamReader(info, stream, bigIntToNumber(streamHeader.totalLength)), {
21748
- identity: participantIdentity
22161
+ yield this.engine.publishRpcAck(callerIdentity, requestId);
22162
+ if (version2 !== 1) {
22163
+ yield this.engine.publishRpcResponse(callerIdentity, requestId, null, RpcError.builtIn("UNSUPPORTED_VERSION"));
22164
+ return;
22165
+ }
22166
+ const handler = this.rpcHandlers.get(method);
22167
+ if (!handler) {
22168
+ yield this.engine.publishRpcResponse(callerIdentity, requestId, null, RpcError.builtIn("UNSUPPORTED_METHOD"));
22169
+ return;
22170
+ }
22171
+ let responseError = null;
22172
+ let responsePayload = null;
22173
+ try {
22174
+ const response = yield handler({
22175
+ requestId,
22176
+ callerIdentity,
22177
+ payload,
22178
+ responseTimeout
21749
22179
  });
21750
- } else if (streamHeader.contentHeader.case === "textHeader") {
21751
- const streamHandlerCallback = this.textStreamHandlers.get(streamHeader.topic);
21752
- if (!streamHandlerCallback) {
21753
- this.log.debug("ignoring incoming text stream due to no handler for topic", streamHeader.topic);
21754
- return;
22180
+ if (byteLength(response) > MAX_PAYLOAD_BYTES) {
22181
+ responseError = RpcError.builtIn("RESPONSE_PAYLOAD_TOO_LARGE");
22182
+ console.warn("RPC Response payload too large for ".concat(method));
22183
+ } else {
22184
+ responsePayload = response;
22185
+ }
22186
+ } catch (error) {
22187
+ if (error instanceof RpcError) {
22188
+ responseError = error;
22189
+ } else {
22190
+ console.warn("Uncaught error returned by RPC handler for ".concat(method, ". Returning APPLICATION_ERROR instead."), error);
22191
+ responseError = RpcError.builtIn("APPLICATION_ERROR");
21755
22192
  }
21756
- let streamController;
21757
- const info = {
21758
- id: streamHeader.streamId,
21759
- mimeType: streamHeader.mimeType,
21760
- size: streamHeader.totalLength ? Number(streamHeader.totalLength) : void 0,
21761
- topic: streamHeader.topic,
21762
- timestamp: Number(streamHeader.timestamp),
21763
- attributes: streamHeader.attributes
21764
- };
21765
- const stream = new ReadableStream({
21766
- start: (controller) => {
21767
- streamController = controller;
21768
- this.textStreamControllers.set(streamHeader.streamId, {
21769
- info,
21770
- controller: streamController,
21771
- startTime: Date.now()
21772
- });
21773
- }
21774
- });
21775
- streamHandlerCallback(new TextStreamReader(info, stream, bigIntToNumber(streamHeader.totalLength)), {
21776
- identity: participantIdentity
21777
- });
21778
22193
  }
22194
+ yield this.engine.publishRpcResponse(callerIdentity, requestId, responsePayload, responseError);
21779
22195
  });
21780
22196
  }
21781
- handleStreamChunk(chunk) {
21782
- const fileBuffer = this.byteStreamControllers.get(chunk.streamId);
21783
- if (fileBuffer) {
21784
- if (chunk.content.length > 0) {
21785
- fileBuffer.controller.enqueue(chunk);
21786
- }
21787
- }
21788
- const textBuffer = this.textStreamControllers.get(chunk.streamId);
21789
- if (textBuffer) {
21790
- if (chunk.content.length > 0) {
21791
- textBuffer.controller.enqueue(chunk);
21792
- }
21793
- }
21794
- }
21795
- handleStreamTrailer(trailer) {
21796
- const textBuffer = this.textStreamControllers.get(trailer.streamId);
21797
- if (textBuffer) {
21798
- textBuffer.info.attributes = Object.assign(Object.assign({}, textBuffer.info.attributes), trailer.attributes);
21799
- textBuffer.controller.close();
21800
- this.textStreamControllers.delete(trailer.streamId);
21801
- }
21802
- const fileBuffer = this.byteStreamControllers.get(trailer.streamId);
21803
- if (fileBuffer) {
21804
- {
21805
- fileBuffer.info.attributes = Object.assign(Object.assign({}, fileBuffer.info.attributes), trailer.attributes);
21806
- fileBuffer.controller.close();
21807
- this.byteStreamControllers.delete(trailer.streamId);
21808
- }
21809
- }
21810
- }
21811
22197
  /**
21812
22198
  * attempt to select the default devices if the previously selected devices are no longer available after a device change event
21813
22199
  */
@@ -22916,6 +23302,13 @@ function getInteractiveElements() {
22916
23302
  }
22917
23303
  function getImmediateText(element3) {
22918
23304
  let text7 = "";
23305
+ const textAttributes = ["label", "text", "placeholder", "title", "alt", "aria-label"];
23306
+ for (const attr of textAttributes) {
23307
+ const value = element3.getAttribute(attr);
23308
+ if (value) {
23309
+ text7 += value + " ";
23310
+ }
23311
+ }
22919
23312
  if (element3.childNodes) {
22920
23313
  for (const node2 of Array.from(element3.childNodes)) {
22921
23314
  if (node2.nodeType === 3) {
@@ -22925,12 +23318,30 @@ function getImmediateText(element3) {
22925
23318
  }
22926
23319
  return text7.trim();
22927
23320
  }
22928
- function captureFullDOMStructure() {
22929
- console.log("\u{1F333} Capturing full DOM structure for Cuekit...");
22930
- const interactiveElements = [];
23321
+ function executeAction(action) {
23322
+ console.log("\u{1F3AF} Executing element action:", action);
23323
+ const { action_type, target_element, target } = action;
23324
+ switch (action_type) {
23325
+ case "click":
23326
+ return clickElement(target_element);
23327
+ case "navigate":
23328
+ return navigateToElement(target_element || target);
23329
+ case "input":
23330
+ case "focus":
23331
+ return focusElement(target_element);
23332
+ case "toggle":
23333
+ return toggleElement(target_element);
23334
+ default:
23335
+ console.warn(`\u26A0\uFE0F Unknown action type: ${action_type}`);
23336
+ return false;
23337
+ }
23338
+ }
23339
+ function captureAllInteractiveElements() {
23340
+ console.log("\u{1F333} Capturing ALL interactive elements for Cuekit...");
23341
+ const interactiveElements = {};
22931
23342
  const descriptionsMap = /* @__PURE__ */ new Map();
22932
- document.querySelectorAll("[data-for]").forEach((el) => {
22933
- const targetId = el.getAttribute("data-for");
23343
+ document.querySelectorAll("[data-ansyr-for]").forEach((el) => {
23344
+ const targetId = el.getAttribute("data-ansyr-for");
22934
23345
  if (!targetId) return;
22935
23346
  const tags = [];
22936
23347
  const description = el.getAttribute("data-ansyr-description");
@@ -22945,110 +23356,115 @@ function captureFullDOMStructure() {
22945
23356
  descriptionsMap.set(targetId, [...existingTags, ...tags]);
22946
23357
  }
22947
23358
  });
22948
- const allElements = getInteractiveElements();
22949
- allElements.forEach((element3) => {
23359
+ const allInteractiveElements = getInteractiveElements();
23360
+ console.log("\u{1F333} Found", allInteractiveElements.length, "interactive elements");
23361
+ allInteractiveElements.forEach((element3) => {
23362
+ if (!(element3 instanceof HTMLElement)) return;
22950
23363
  const style = getComputedStyle(element3);
22951
- if (element3.closest("[data-cuekit-ignore]") || !isElementClickable(element3) || element3.tagName.toLowerCase() === "script" || style.display === "none" || style.visibility === "hidden") {
23364
+ if (element3.closest("[data-cuekit-ignore]") || element3.tagName.toLowerCase() === "script" || style.display === "none" || style.visibility === "hidden") {
22952
23365
  return;
22953
23366
  }
23367
+ let elementId = null;
22954
23368
  const staticId = element3.getAttribute("data-ansyr-static");
22955
23369
  const dynamicId = element3.getAttribute("data-ansyr-dynamic");
22956
- const id = staticId || dynamicId;
23370
+ if (staticId) {
23371
+ elementId = staticId;
23372
+ console.log("\u{1F333} Using pre-assigned static ID:", elementId);
23373
+ } else if (dynamicId) {
23374
+ elementId = dynamicId;
23375
+ console.log("\u{1F333} Using pre-assigned dynamic ID:", elementId);
23376
+ } else {
23377
+ elementId = generateStableDOMId(element3);
23378
+ console.log("\u{1F333} Calculated stable DOM ID:", elementId);
23379
+ }
23380
+ if (!elementId) {
23381
+ console.log("\u{1F333} No ID could be determined for element:", element3);
23382
+ return;
23383
+ }
22957
23384
  const tags = [];
22958
23385
  const directDescription = element3.getAttribute("data-ansyr-description");
22959
23386
  if (directDescription) {
22960
23387
  tags.push(directDescription);
22961
23388
  }
22962
- if (id && descriptionsMap.has(id)) {
22963
- tags.push(...descriptionsMap.get(id) || []);
22964
- }
22965
- const dto = {
22966
- testID: id || generateStableDOMId(element3),
22967
- type: element3.tagName.toLowerCase(),
22968
- textContent: getImmediateText(element3) || element3.textContent?.trim() || "",
22969
- tags
22970
- };
22971
- interactiveElements.push(dto);
23389
+ if (descriptionsMap.has(elementId)) {
23390
+ tags.push(...descriptionsMap.get(elementId) || []);
23391
+ }
23392
+ const textContent = getImmediateText(element3) || element3.textContent?.trim() || "";
23393
+ interactiveElements[elementId] = [textContent, ...tags];
23394
+ console.log("\u{1F333} Captured element:", {
23395
+ id: elementId,
23396
+ tagName: element3.tagName,
23397
+ textContent: textContent.substring(0, 50),
23398
+ hasStaticId: !!staticId,
23399
+ hasDynamicId: !!dynamicId,
23400
+ isCalculated: !staticId && !dynamicId
23401
+ });
22972
23402
  });
22973
23403
  const result = {
22974
23404
  components: interactiveElements
22975
23405
  };
22976
- console.log("\u{1F333} Full DOM structure captured:", result);
23406
+ console.log("\u{1F333} All interactive elements captured:", result);
22977
23407
  return result;
22978
23408
  }
22979
- function isElementClickable(element3) {
22980
- const interactiveSelectors = [
22981
- "button",
22982
- "a",
22983
- "input",
22984
- "select",
22985
- "textarea",
22986
- '[role="button"]',
22987
- '[role="link"]',
22988
- '[role="tab"]',
22989
- "[data-onclick-id]",
22990
- "[data-on-press-id]",
22991
- "[onclick]",
22992
- "[onmousedown]",
22993
- "[onmouseup]",
22994
- "[ontouchstart]",
22995
- "[ontouchend]",
22996
- "[onkeydown]",
22997
- "[onkeyup]",
22998
- "[onkeypress]"
22999
- ];
23000
- for (const selector of interactiveSelectors) {
23001
- if (element3.matches(selector)) {
23002
- return true;
23003
- }
23004
- }
23005
- const hasClickEvents = element3.onclick !== null || element3.getAttribute("onclick") !== null;
23006
- const hasInteractiveEvents = element3.ontouchstart !== null || element3.getAttribute("ontouchstart") !== null || element3.ontouchend !== null || element3.getAttribute("ontouchend") !== null || element3.onkeydown !== null || element3.getAttribute("onkeydown") !== null || element3.onkeyup !== null || element3.getAttribute("onkeyup") !== null || element3.onkeypress !== null || element3.getAttribute("onkeypress") !== null;
23007
- const hasPointerCursor = element3.style.cursor === "pointer" || getComputedStyle(element3).cursor === "pointer";
23008
- const hasTabIndex = element3.hasAttribute("tabindex") && parseInt(element3.getAttribute("tabindex") || "0") >= 0;
23009
- const hasInteractiveDataAttrs = element3.hasAttribute("data-clickable") || element3.hasAttribute("data-interactive") || element3.hasAttribute("data-action") || element3.hasAttribute("data-handler");
23010
- const hasInteractiveAria = element3.hasAttribute("aria-pressed") || element3.hasAttribute("aria-expanded") || element3.hasAttribute("aria-selected") || element3.hasAttribute("aria-checked");
23011
- return hasClickEvents || hasInteractiveEvents || hasPointerCursor || hasTabIndex || hasInteractiveDataAttrs || hasInteractiveAria;
23409
+ function clearElementCache() {
23410
+ elementCache.clear();
23411
+ cacheTimestamp = 0;
23012
23412
  }
23013
- function executeAction(action) {
23014
- console.log("\u{1F3AF} Executing element action:", action);
23015
- const { action_type, target_element, target } = action;
23016
- switch (action_type) {
23017
- case "click":
23018
- return clickElement(target_element);
23019
- case "navigate":
23020
- return navigateToElement(target_element || target);
23021
- case "input":
23022
- case "focus":
23023
- return focusElement(target_element);
23024
- case "toggle":
23025
- return toggleElement(target_element);
23026
- default:
23027
- console.warn(`\u26A0\uFE0F Unknown action type: ${action_type}`);
23028
- return false;
23413
+ function validateDynamicElements() {
23414
+ if (false) {
23415
+ const elements = document.querySelectorAll("[data-ansyr-dynamic]");
23416
+ const ids = /* @__PURE__ */ new Set();
23417
+ const duplicates = [];
23418
+ elements.forEach((element3) => {
23419
+ const id = element3.getAttribute("data-ansyr-dynamic");
23420
+ if (id) {
23421
+ if (ids.has(id)) {
23422
+ duplicates.push(id);
23423
+ }
23424
+ ids.add(id);
23425
+ }
23426
+ });
23427
+ if (duplicates.length > 0) {
23428
+ console.warn("\u{1F6A8} CueKit: Duplicate dynamic IDs found:", duplicates);
23429
+ console.warn(
23430
+ "This can cause incorrect element targeting. Ensure each dynamic element has a unique identifier."
23431
+ );
23432
+ }
23029
23433
  }
23030
23434
  }
23031
- function getFullDOMStructure() {
23032
- return captureFullDOMStructure();
23033
- }
23034
23435
  function clickElement(elementId) {
23436
+ console.log("\u{1F5B1}\uFE0F clickElement called with:", elementId);
23035
23437
  if (!elementId) {
23438
+ console.log("\u{1F5B1}\uFE0F clickElement: no elementId provided");
23036
23439
  return false;
23037
23440
  }
23038
23441
  const domElement = findDOMElementById(elementId);
23442
+ console.log("\u{1F5B1}\uFE0F clickElement: found DOM element:", domElement);
23039
23443
  if (domElement) {
23444
+ console.log("\u{1F5B1}\uFE0F clickElement: attempting to click element:", {
23445
+ tagName: domElement.tagName,
23446
+ id: domElement.id,
23447
+ className: domElement.className,
23448
+ textContent: domElement.textContent?.substring(0, 50)
23449
+ });
23040
23450
  domElement.click();
23451
+ console.log("\u{1F5B1}\uFE0F clickElement: click() called successfully");
23041
23452
  return true;
23042
23453
  }
23454
+ console.log("\u{1F5B1}\uFE0F clickElement: element not found");
23043
23455
  return false;
23044
23456
  }
23045
23457
  function navigateToElement(target) {
23458
+ console.log("\u{1F9ED} navigateToElement called with:", target);
23046
23459
  if (!target) {
23460
+ console.log("\u{1F9ED} navigateToElement: no target provided");
23047
23461
  return false;
23048
23462
  }
23049
23463
  if (target.includes("/") || target.startsWith("http")) {
23464
+ console.log("\u{1F9ED} navigateToElement: using safeNavigate for path:", target);
23050
23465
  safeNavigate(target, {});
23051
23466
  } else {
23467
+ console.log("\u{1F9ED} navigateToElement: using handleNavigationAndClick for element:", target);
23052
23468
  handleNavigationAndClick(target, target);
23053
23469
  }
23054
23470
  return true;
@@ -23087,29 +23503,93 @@ function toggleElement(elementId) {
23087
23503
  }
23088
23504
  }
23089
23505
  function findDOMElementById(elementId) {
23506
+ console.log("\u{1F50D} findDOMElementById called with:", elementId);
23090
23507
  if (!elementId) {
23508
+ console.log("\u{1F50D} findDOMElementById: no elementId provided");
23091
23509
  return null;
23092
23510
  }
23093
- const interactiveElements = getInteractiveElements();
23094
- for (const element3 of interactiveElements) {
23095
- if (element3 instanceof HTMLElement) {
23511
+ const now = Date.now();
23512
+ if (now - cacheTimestamp < CACHE_TTL && elementCache.has(elementId)) {
23513
+ const cachedElement = elementCache.get(elementId);
23514
+ console.log("\u{1F50D} findDOMElementById: found in cache:", cachedElement);
23515
+ if (document.contains(cachedElement)) {
23516
+ console.log("\u{1F50D} findDOMElementById: returning cached element");
23517
+ return cachedElement;
23518
+ } else {
23519
+ console.log("\u{1F50D} findDOMElementById: cached element no longer in DOM, removing from cache");
23520
+ elementCache.delete(elementId);
23521
+ }
23522
+ }
23523
+ let foundElement = null;
23524
+ console.log(
23525
+ "\u{1F50D} findDOMElementById: checking for static element with selector:",
23526
+ `[data-ansyr-static="${elementId}"]`
23527
+ );
23528
+ const staticElement = document.querySelector(`[data-ansyr-static="${elementId}"]`);
23529
+ if (staticElement instanceof HTMLElement) {
23530
+ console.log("\u{1F50D} findDOMElementById: found static element:", staticElement);
23531
+ foundElement = staticElement;
23532
+ } else {
23533
+ console.log(
23534
+ "\u{1F50D} findDOMElementById: checking for dynamic element with selector:",
23535
+ `[data-ansyr-dynamic="${elementId}"]`
23536
+ );
23537
+ const dynamicElement = document.querySelector(`[data-ansyr-dynamic="${elementId}"]`);
23538
+ if (dynamicElement instanceof HTMLElement) {
23539
+ console.log("\u{1F50D} findDOMElementById: found dynamic element:", dynamicElement);
23540
+ foundElement = dynamicElement;
23541
+ }
23542
+ }
23543
+ if (!foundElement) {
23544
+ console.log(
23545
+ "\u{1F50D} findDOMElementById: no pre-assigned element found, scanning all interactive elements"
23546
+ );
23547
+ const interactiveElements = getInteractiveElements();
23548
+ console.log("\u{1F50D} findDOMElementById: found", interactiveElements.length, "interactive elements");
23549
+ for (const element3 of interactiveElements) {
23550
+ if (!(element3 instanceof HTMLElement)) continue;
23096
23551
  const staticId = element3.getAttribute("data-ansyr-static");
23097
23552
  const dynamicId = element3.getAttribute("data-ansyr-dynamic");
23098
- const currentElementId = staticId || dynamicId || generateStableDOMId(element3);
23553
+ let currentElementId = null;
23554
+ if (staticId) {
23555
+ currentElementId = staticId;
23556
+ } else if (dynamicId) {
23557
+ currentElementId = dynamicId;
23558
+ } else {
23559
+ currentElementId = generateStableDOMId(element3);
23560
+ }
23099
23561
  if (currentElementId === elementId) {
23100
- return element3;
23562
+ console.log("\u{1F50D} findDOMElementById: found element by ID match:", {
23563
+ element: element3,
23564
+ id: currentElementId,
23565
+ hasStaticId: !!staticId,
23566
+ hasDynamicId: !!dynamicId,
23567
+ isCalculated: !staticId && !dynamicId
23568
+ });
23569
+ foundElement = element3;
23570
+ break;
23101
23571
  }
23102
23572
  }
23573
+ if (!foundElement) {
23574
+ console.log("\u{1F50D} findDOMElementById: element not found in interactive elements scan");
23575
+ }
23103
23576
  }
23104
- return null;
23577
+ if (foundElement) {
23578
+ elementCache.set(elementId, foundElement);
23579
+ cacheTimestamp = now;
23580
+ }
23581
+ return foundElement;
23105
23582
  }
23106
- var INTERACTIVE_ELEMENT_SELECTOR;
23583
+ var INTERACTIVE_ELEMENT_SELECTOR, elementCache, cacheTimestamp, CACHE_TTL;
23107
23584
  var init_element_service = __esm({
23108
23585
  "src/utils/element-service.ts"() {
23109
23586
  "use strict";
23110
23587
  init_navigation();
23111
23588
  init_jsx_encoder();
23112
- INTERACTIVE_ELEMENT_SELECTOR = 'a, button, input, textarea, select, [role="button"], [onclick], [data-ansyr-static], [data-ansyr-dynamic]';
23589
+ INTERACTIVE_ELEMENT_SELECTOR = 'a, button, select, [role="button"], [role="link"], [role="tab"], [onclick], [onmousedown], [onmouseup], [ontouchstart], [ontouchend], [onkeydown], [onkeyup], [onkeypress], [onchange], [onsubmit], [onfocus], [onblur], [data-ansyr-static], [data-ansyr-dynamic]';
23590
+ elementCache = /* @__PURE__ */ new Map();
23591
+ cacheTimestamp = 0;
23592
+ CACHE_TTL = 5e3;
23113
23593
  }
23114
23594
  });
23115
23595
 
@@ -23119,6 +23599,7 @@ __export(webrtc_service_exports, {
23119
23599
  authenticate: () => authenticate,
23120
23600
  connectToRoom: () => connectToRoom,
23121
23601
  disconnectFromRoom: () => disconnectFromRoom,
23602
+ getCurrentCallbacks: () => getCurrentCallbacks,
23122
23603
  getParticipants: () => getParticipants,
23123
23604
  getRoom: () => getRoom,
23124
23605
  getRoomName: () => getRoomName,
@@ -23139,8 +23620,16 @@ function setAudioContainer(newAudioContainerRef) {
23139
23620
  audioContainerRef = newAudioContainerRef;
23140
23621
  }
23141
23622
  function setWebRTCCallbacks(newCallbacks) {
23623
+ console.log("\u{1F4E1} setWebRTCCallbacks called with:", {
23624
+ hasOnNavigationCommand: !!newCallbacks.onNavigationCommand,
23625
+ hasOnConnectionStateChange: !!newCallbacks.onConnectionStateChange,
23626
+ hasOnParticipantUpdate: !!newCallbacks.onParticipantUpdate
23627
+ });
23142
23628
  callbacks = newCallbacks;
23143
23629
  }
23630
+ function getCurrentCallbacks() {
23631
+ return callbacks;
23632
+ }
23144
23633
  async function authenticate(userIdentity, apiKey, appId) {
23145
23634
  try {
23146
23635
  const authPayload = {
@@ -23231,12 +23720,34 @@ function setupEventListeners() {
23231
23720
  track.detach().forEach((element3) => element3.remove());
23232
23721
  }).on(RoomEvent.DataReceived, (payload, participant) => {
23233
23722
  const decodedPayload = new TextDecoder().decode(payload);
23234
- try {
23235
- const message = JSON.parse(decodedPayload);
23236
- callbacks.onNavigationCommand?.(message);
23237
- } catch (error) {
23238
- const message = decodedPayload;
23239
- callbacks.onNavigationCommand?.({ type: "raw_text", data: message });
23723
+ console.log("\u{1F4E1} WebRTC DataReceived:", { decodedPayload, participant: participant?.identity });
23724
+ if (decodedPayload.includes("|")) {
23725
+ const parts = decodedPayload.split("|");
23726
+ const textPart = parts[0];
23727
+ const jsonPart = parts[1];
23728
+ console.log("\u{1F4E1} WebRTC Pipe-separated message:", { textPart, jsonPart });
23729
+ if (textPart) {
23730
+ callbacks.onNavigationCommand?.({ type: "speech_text", data: textPart });
23731
+ }
23732
+ if (jsonPart) {
23733
+ try {
23734
+ const message = JSON.parse(jsonPart);
23735
+ console.log("\u{1F4E1} WebRTC Parsed JSON message:", message);
23736
+ callbacks.onNavigationCommand?.(message);
23737
+ } catch (error) {
23738
+ console.log("\u{1F4E1} WebRTC JSON parse error for JSON part:", error, "JSON part:", jsonPart);
23739
+ }
23740
+ }
23741
+ } else {
23742
+ try {
23743
+ const message = JSON.parse(decodedPayload);
23744
+ console.log("\u{1F4E1} WebRTC Parsed message:", message);
23745
+ callbacks.onNavigationCommand?.(message);
23746
+ } catch (error) {
23747
+ console.log("\u{1F4E1} WebRTC JSON parse error:", error, "Raw payload:", decodedPayload);
23748
+ const message = decodedPayload;
23749
+ callbacks.onNavigationCommand?.({ type: "raw_text", data: message });
23750
+ }
23240
23751
  }
23241
23752
  }).on(RoomEvent.Disconnected, () => {
23242
23753
  setWebRTCConnectionState({ isConnected: false, isConnecting: false });
@@ -23290,17 +23801,19 @@ async function sendUserCommand(command) {
23290
23801
  await sendData(command);
23291
23802
  }
23292
23803
  async function sendRuntimeData() {
23804
+ console.log("\u{1F9E0} checking room:", room);
23293
23805
  if (!room) {
23294
23806
  return;
23295
23807
  }
23808
+ console.log("\u{1F9E0} Sending runtime data", room);
23296
23809
  try {
23297
- const domStructure = captureFullDOMStructure();
23810
+ const allInteractiveElements = captureAllInteractiveElements();
23298
23811
  const screenName = getCurrentScreenName();
23299
23812
  const response = {
23300
23813
  type: "runtime_data_response",
23301
23814
  data: {
23302
- components: domStructure.components,
23303
- current_screen: screenName
23815
+ components: allInteractiveElements.components,
23816
+ currentRoute: screenName
23304
23817
  }
23305
23818
  };
23306
23819
  await sendData(JSON.stringify(response));
@@ -23722,7 +24235,7 @@ var require_core = __commonJS({
23722
24235
  root4.CryptoJS = factory();
23723
24236
  }
23724
24237
  })(exports, function() {
23725
- var CryptoJS = CryptoJS || function(Math2, undefined2) {
24238
+ var CryptoJS = CryptoJS || (function(Math2, undefined2) {
23726
24239
  var crypto2;
23727
24240
  if (typeof window !== "undefined" && window.crypto) {
23728
24241
  crypto2 = window.crypto;
@@ -23762,7 +24275,7 @@ var require_core = __commonJS({
23762
24275
  }
23763
24276
  throw new Error("Native crypto module could not be used to get secure random number.");
23764
24277
  };
23765
- var create2 = Object.create || /* @__PURE__ */ function() {
24278
+ var create2 = Object.create || /* @__PURE__ */ (function() {
23766
24279
  function F2() {
23767
24280
  }
23768
24281
  return function(obj) {
@@ -23772,10 +24285,10 @@ var require_core = __commonJS({
23772
24285
  F2.prototype = null;
23773
24286
  return subtype;
23774
24287
  };
23775
- }();
24288
+ })();
23776
24289
  var C = {};
23777
24290
  var C_lib = C.lib = {};
23778
- var Base = C_lib.Base = /* @__PURE__ */ function() {
24291
+ var Base = C_lib.Base = /* @__PURE__ */ (function() {
23779
24292
  return {
23780
24293
  /**
23781
24294
  * Creates a new object that inherits from this object.
@@ -23874,7 +24387,7 @@ var require_core = __commonJS({
23874
24387
  return this.init.prototype.extend(this);
23875
24388
  }
23876
24389
  };
23877
- }();
24390
+ })();
23878
24391
  var WordArray = C_lib.WordArray = Base.extend({
23879
24392
  /**
23880
24393
  * Initializes a newly created word array.
@@ -24312,7 +24825,7 @@ var require_core = __commonJS({
24312
24825
  });
24313
24826
  var C_algo = C.algo = {};
24314
24827
  return C;
24315
- }(Math);
24828
+ })(Math);
24316
24829
  return CryptoJS;
24317
24830
  });
24318
24831
  }
@@ -24507,17 +25020,20 @@ __export(index_exports, {
24507
25020
  InitCuekit: () => InitCuekit,
24508
25021
  MicButton: () => MicButton,
24509
25022
  VoiceIntensityVisualizer: () => VoiceIntensityVisualizer,
24510
- captureFullDOMStructure: () => captureFullDOMStructure,
25023
+ captureAllInteractiveElements: () => captureAllInteractiveElements,
25024
+ clearElementCache: () => clearElementCache,
24511
25025
  configureWebRTCServer: () => configureWebRTCServer,
24512
25026
  executeAction: () => executeAction,
24513
25027
  generateDynamicId: () => generateDynamicId,
24514
- getFullDOMStructure: () => getFullDOMStructure,
25028
+ getCurrentPathParams: () => getCurrentPathParams,
24515
25029
  getWebRTCServerConfig: () => getWebRTCServerConfig,
24516
25030
  initWebRTC: () => initWebRTC,
24517
25031
  initWebRTCWithDeployedBackend: () => initWebRTCWithDeployedBackend,
25032
+ resolveRoutePath: () => resolveRoutePath,
24518
25033
  useCuekit: () => useCuekit,
24519
25034
  useQubeContext: () => useQubeContext,
24520
- useWebRTC: () => useWebRTC
25035
+ useWebRTC: () => useWebRTC,
25036
+ validateDynamicElements: () => validateDynamicElements
24521
25037
  });
24522
25038
  module.exports = __toCommonJS(index_exports);
24523
25039
 
@@ -24651,25 +25167,12 @@ var CuekitProvider = ({
24651
25167
  Promise.resolve().then(() => (init_webrtc_service(), webrtc_service_exports)).then(({ setWebRTCCallbacks: setWebRTCCallbacks2 }) => {
24652
25168
  setWebRTCCallbacks2({
24653
25169
  onNavigationCommand: (command) => {
24654
- switch (command.type) {
24655
- case "static_data_ready":
24656
- break;
24657
- case "ai_intent":
24658
- if (command.actionType === "navigate" && command.current_page) {
24659
- if (navigationHandler2) {
24660
- navigationHandler2(command.current_page, {
24661
- intent: command.intent,
24662
- text: command.text,
24663
- confidence: command.confidence
24664
- });
24665
- }
24666
- }
24667
- break;
24668
- case "user_speech_text":
24669
- break;
24670
- case "ai_speech_text":
24671
- break;
24672
- default:
25170
+ if (command.data.actionType === "navigate" && command.data.routeName) {
25171
+ if (navigationHandler2) {
25172
+ navigationHandler2(command.data.routeName);
25173
+ }
25174
+ } else if (command.data.actionType === "click" && command.data.elementId) {
25175
+ console.log("AI intent: Click element", command.data.elementId);
24673
25176
  }
24674
25177
  },
24675
25178
  onConnectionStateChange: (state) => {
@@ -24754,6 +25257,7 @@ var import_react15 = __toESM(require("react"));
24754
25257
 
24755
25258
  // src/hooks/use-cuekit.ts
24756
25259
  var import_react3 = require("react");
25260
+ init_livekit_client_esm();
24757
25261
 
24758
25262
  // src/hooks/use-webrtc.ts
24759
25263
  var import_react2 = require("react");
@@ -24894,9 +25398,18 @@ var useCuekit = (options) => {
24894
25398
  }, []);
24895
25399
  const [micState, setMicState] = (0, import_react3.useState)("idle");
24896
25400
  const [status, setStatus] = (0, import_react3.useState)("");
25401
+ const [muteState, setMuteState] = (0, import_react3.useState)({ isMuted: false, canMute: false });
24897
25402
  const handleNavigationCommand = (event) => {
24898
25403
  console.log(`\u2B07\uFE0F Received event from backend: ${event.type}`, event);
24899
25404
  switch (event.type) {
25405
+ case "speech_text": {
25406
+ console.log("\u{1F5E3}\uFE0F AI Speech text:", event.data);
25407
+ break;
25408
+ }
25409
+ case "raw_text": {
25410
+ console.log("\u{1F4DD} Raw text message:", event.data);
25411
+ break;
25412
+ }
24900
25413
  case "user_speech_chunk":
24901
25414
  case "ai_speech_chunk": {
24902
25415
  const role = event.type === "user_speech_chunk" ? "user" : "ai";
@@ -24932,16 +25445,37 @@ var useCuekit = (options) => {
24932
25445
  }
24933
25446
  case "ai_intent": {
24934
25447
  const intent = event.data;
24935
- if (intent.actionType === "click" && intent.actionMetadata.elementId) {
25448
+ console.log("\u{1F3AF} AI Intent received:", intent);
25449
+ if (intent.actionType === "click" && intent.elementId) {
25450
+ console.log("\u{1F3AF} Executing click action:", intent.elementId);
24936
25451
  executeAction({
24937
25452
  action_type: "click",
24938
- target_element: intent.actionMetadata.elementId
25453
+ target_element: intent.elementId
24939
25454
  });
24940
- } else if (intent.actionType === "navigate" && intent.actionMetadata.routeName) {
25455
+ } else if (intent.actionType === "navigate" && intent.routeName) {
25456
+ console.log("\u{1F3AF} Executing navigate action:", intent.routeName);
24941
25457
  executeAction({
24942
25458
  action_type: "navigate",
24943
- target_element: intent.actionMetadata.routeName
25459
+ target_element: intent.routeName
24944
25460
  });
25461
+ } else {
25462
+ console.log("\u{1F3AF} AI Intent not handled:", intent);
25463
+ }
25464
+ break;
25465
+ }
25466
+ case "chat": {
25467
+ const chatData = event.data;
25468
+ console.log("\u{1F4AC} Chat message received:", chatData);
25469
+ if (chatData.message && chatData.sender === "ai") {
25470
+ const newMessage = {
25471
+ id: `ai-${Date.now()}`,
25472
+ role: "ai",
25473
+ text: chatData.message,
25474
+ isFinal: true,
25475
+ timestamp: new Date(chatData.timestamp || Date.now()).toISOString()
25476
+ };
25477
+ setMessages((prev) => [...prev, newMessage]);
25478
+ setMicState("listening");
24945
25479
  }
24946
25480
  break;
24947
25481
  }
@@ -24977,17 +25511,21 @@ var useCuekit = (options) => {
24977
25511
  switch (state) {
24978
25512
  case "connecting":
24979
25513
  setStatus("Connecting...");
25514
+ setMuteState((prev) => ({ ...prev, canMute: false }));
24980
25515
  break;
24981
25516
  case "connected":
24982
25517
  setStatus("");
24983
25518
  setMicState("listening");
25519
+ setMuteState((prev) => ({ ...prev, canMute: true }));
24984
25520
  break;
24985
25521
  case "disconnected":
24986
25522
  setStatus("Disconnected");
24987
25523
  setMicState("idle");
25524
+ setMuteState({ isMuted: false, canMute: false });
24988
25525
  break;
24989
25526
  case "reconnecting":
24990
25527
  setStatus("Reconnecting...");
25528
+ setMuteState((prev) => ({ ...prev, canMute: false }));
24991
25529
  break;
24992
25530
  default:
24993
25531
  break;
@@ -25009,7 +25547,88 @@ var useCuekit = (options) => {
25009
25547
  await webrtc.disconnect();
25010
25548
  clearMessages();
25011
25549
  setMicState("idle");
25550
+ setMuteState({ isMuted: false, canMute: false });
25012
25551
  }, [webrtc, clearMessages]);
25552
+ const toggleMute = (0, import_react3.useCallback)(async () => {
25553
+ if (!webrtc.isConnected) return;
25554
+ try {
25555
+ const room2 = webrtc.room;
25556
+ if (!room2) return;
25557
+ const localParticipant = room2.localParticipant;
25558
+ const audioTrack = localParticipant.getTrackPublication(Track.Source.Microphone)?.track;
25559
+ if (audioTrack) {
25560
+ if (muteState.isMuted) {
25561
+ await audioTrack.unmute();
25562
+ setMuteState((prev) => ({ ...prev, isMuted: false }));
25563
+ } else {
25564
+ await audioTrack.mute();
25565
+ setMuteState((prev) => ({ ...prev, isMuted: true }));
25566
+ }
25567
+ }
25568
+ } catch (error) {
25569
+ console.error("Failed to toggle mute:", error);
25570
+ }
25571
+ }, [webrtc, muteState.isMuted]);
25572
+ const setMute = (0, import_react3.useCallback)(
25573
+ async (muted) => {
25574
+ if (!webrtc.isConnected) return;
25575
+ try {
25576
+ const room2 = webrtc.room;
25577
+ if (!room2) return;
25578
+ const localParticipant = room2.localParticipant;
25579
+ const audioTrack = localParticipant.getTrackPublication(Track.Source.Microphone)?.track;
25580
+ if (audioTrack) {
25581
+ if (muted && !muteState.isMuted) {
25582
+ await audioTrack.mute();
25583
+ setMuteState((prev) => ({ ...prev, isMuted: true }));
25584
+ } else if (!muted && muteState.isMuted) {
25585
+ await audioTrack.unmute();
25586
+ setMuteState((prev) => ({ ...prev, isMuted: false }));
25587
+ }
25588
+ }
25589
+ } catch (error) {
25590
+ console.error("Failed to set mute:", error);
25591
+ }
25592
+ },
25593
+ [webrtc, muteState.isMuted]
25594
+ );
25595
+ const sendChatMessage = (0, import_react3.useCallback)(
25596
+ async (message) => {
25597
+ if (!webrtc.isConnected) {
25598
+ console.warn("Cannot send chat message: not connected to LiveKit");
25599
+ return;
25600
+ }
25601
+ try {
25602
+ const room2 = webrtc.room;
25603
+ if (!room2) return;
25604
+ const payload = {
25605
+ type: "chat",
25606
+ message,
25607
+ timestamp: Date.now(),
25608
+ sender: "user"
25609
+ };
25610
+ console.log("\u{1F4E4} Sending chat message via LiveKit:", payload);
25611
+ const encoder = new TextEncoder();
25612
+ const encodedData = encoder.encode(JSON.stringify(payload));
25613
+ await room2.localParticipant.publishData(encodedData, {
25614
+ reliable: true
25615
+ });
25616
+ const newMessage = {
25617
+ id: `user-${Date.now()}`,
25618
+ role: "user",
25619
+ text: message,
25620
+ isFinal: true,
25621
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
25622
+ };
25623
+ setMessages((prev) => [...prev, newMessage]);
25624
+ setMicState("thinking");
25625
+ } catch (error) {
25626
+ console.error("Failed to send chat message:", error);
25627
+ throw error;
25628
+ }
25629
+ },
25630
+ [webrtc]
25631
+ );
25013
25632
  return {
25014
25633
  ...webrtc,
25015
25634
  messages,
@@ -25018,12 +25637,16 @@ var useCuekit = (options) => {
25018
25637
  status,
25019
25638
  setStatus,
25020
25639
  connect,
25021
- disconnect
25640
+ disconnect,
25641
+ muteState,
25642
+ toggleMute,
25643
+ setMute,
25644
+ sendChatMessage
25022
25645
  };
25023
25646
  };
25024
25647
 
25025
25648
  // src/components/chat-popup.tsx
25026
- var import_react9 = __toESM(require("react"));
25649
+ var import_react11 = __toESM(require("react"));
25027
25650
 
25028
25651
  // node_modules/devlop/lib/default.js
25029
25652
  function ok() {
@@ -32620,7 +33243,7 @@ var convert = (
32620
33243
  * @param {Test} [test]
32621
33244
  * @returns {Check}
32622
33245
  */
32623
- function(test) {
33246
+ (function(test) {
32624
33247
  if (test === null || test === void 0) {
32625
33248
  return ok2;
32626
33249
  }
@@ -32634,7 +33257,7 @@ var convert = (
32634
33257
  return typeFactory(test);
32635
33258
  }
32636
33259
  throw new Error("Expected function, string, or object as test");
32637
- }
33260
+ })
32638
33261
  );
32639
33262
  function anyFactory(tests) {
32640
33263
  const checks2 = [];
@@ -33814,7 +34437,7 @@ var CallableInstance = (
33814
34437
  * @param {string | symbol} property
33815
34438
  * @returns {(...parameters: Array<unknown>) => unknown}
33816
34439
  */
33817
- function(property) {
34440
+ (function(property) {
33818
34441
  const self2 = this;
33819
34442
  const constr = self2.constructor;
33820
34443
  const proto = (
@@ -33829,7 +34452,7 @@ var CallableInstance = (
33829
34452
  };
33830
34453
  Object.setPrototypeOf(apply, proto);
33831
34454
  return apply;
33832
- }
34455
+ })
33833
34456
  );
33834
34457
 
33835
34458
  // node_modules/unified/lib/index.js
@@ -37767,6 +38390,59 @@ var PhoneOffIcon = ({ width = 24, height = 24, className, ...props }) => {
37767
38390
  };
37768
38391
  var phone_off_default = PhoneOffIcon;
37769
38392
 
38393
+ // src/components/svgs/mic-off.tsx
38394
+ var import_react9 = __toESM(require("react"));
38395
+ var MicOffIcon = ({ style, className }) => {
38396
+ return /* @__PURE__ */ import_react9.default.createElement(
38397
+ "svg",
38398
+ {
38399
+ xmlns: "http://www.w3.org/2000/svg",
38400
+ width: "24",
38401
+ height: "24",
38402
+ viewBox: "0 0 24 24",
38403
+ fill: "none",
38404
+ stroke: "currentColor",
38405
+ strokeWidth: "2",
38406
+ strokeLinecap: "round",
38407
+ strokeLinejoin: "round",
38408
+ className: `lucide lucide-mic-off-icon lucide-mic-off ${className || ""}`,
38409
+ style
38410
+ },
38411
+ /* @__PURE__ */ import_react9.default.createElement("path", { d: "M12 19v3" }),
38412
+ /* @__PURE__ */ import_react9.default.createElement("path", { d: "M15 9.34V5a3 3 0 0 0-5.68-1.33" }),
38413
+ /* @__PURE__ */ import_react9.default.createElement("path", { d: "M16.95 16.95A7 7 0 0 1 5 12v-2" }),
38414
+ /* @__PURE__ */ import_react9.default.createElement("path", { d: "M18.89 13.23A7 7 0 0 0 19 12v-2" }),
38415
+ /* @__PURE__ */ import_react9.default.createElement("path", { d: "m2 2 20 20" }),
38416
+ /* @__PURE__ */ import_react9.default.createElement("path", { d: "M9 9v3a3 3 0 0 0 5.12 2.12" })
38417
+ );
38418
+ };
38419
+ var mic_off_default = MicOffIcon;
38420
+
38421
+ // src/components/svgs/mic.tsx
38422
+ var import_react10 = __toESM(require("react"));
38423
+ var MicIcon = ({ width = 24, height = 24, className, ...props }) => {
38424
+ return /* @__PURE__ */ import_react10.default.createElement(
38425
+ "svg",
38426
+ {
38427
+ xmlns: "http://www.w3.org/2000/svg",
38428
+ width,
38429
+ height,
38430
+ viewBox: "0 0 24 24",
38431
+ fill: "none",
38432
+ stroke: "currentColor",
38433
+ strokeWidth: "2",
38434
+ strokeLinecap: "round",
38435
+ strokeLinejoin: "round",
38436
+ className,
38437
+ ...props
38438
+ },
38439
+ /* @__PURE__ */ import_react10.default.createElement("path", { d: "M12 19v3" }),
38440
+ /* @__PURE__ */ import_react10.default.createElement("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
38441
+ /* @__PURE__ */ import_react10.default.createElement("rect", { x: "9", y: "2", width: "6", height: "13", rx: "3" })
38442
+ );
38443
+ };
38444
+ var mic_default = MicIcon;
38445
+
37770
38446
  // src/components/chat-popup.tsx
37771
38447
  var ChatPopup = ({
37772
38448
  isOpen,
@@ -37783,15 +38459,17 @@ var ChatPopup = ({
37783
38459
  currentTheme = "dark",
37784
38460
  onThemeToggle,
37785
38461
  status,
37786
- anchor
38462
+ anchor,
38463
+ muteState,
38464
+ onToggleMute
37787
38465
  }) => {
37788
- const [inputText, setInputText] = (0, import_react9.useState)("");
37789
- const [isSending, setIsSending] = (0, import_react9.useState)(false);
37790
- const messagesEndRef = (0, import_react9.useRef)(null);
38466
+ const [inputText, setInputText] = (0, import_react11.useState)("");
38467
+ const [isSending, setIsSending] = (0, import_react11.useState)(false);
38468
+ const messagesEndRef = (0, import_react11.useRef)(null);
37791
38469
  const scrollToBottom = () => {
37792
38470
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
37793
38471
  };
37794
- (0, import_react9.useEffect)(() => {
38472
+ (0, import_react11.useEffect)(() => {
37795
38473
  console.log("\u{1F4EC} ChatPopup received messages:", JSON.stringify(messages, null, 2));
37796
38474
  scrollToBottom();
37797
38475
  }, [messages]);
@@ -37853,7 +38531,7 @@ var ChatPopup = ({
37853
38531
  }
37854
38532
  };
37855
38533
  const positionStyle = getPositionStyle();
37856
- return /* @__PURE__ */ import_react9.default.createElement(
38534
+ return /* @__PURE__ */ import_react11.default.createElement(
37857
38535
  "div",
37858
38536
  {
37859
38537
  "data-cuekit-ignore": true,
@@ -37876,7 +38554,7 @@ var ChatPopup = ({
37876
38554
  ...positionStyle
37877
38555
  }
37878
38556
  },
37879
- /* @__PURE__ */ import_react9.default.createElement(
38557
+ /* @__PURE__ */ import_react11.default.createElement(
37880
38558
  "div",
37881
38559
  {
37882
38560
  style: {
@@ -37887,14 +38565,14 @@ var ChatPopup = ({
37887
38565
  justifyContent: "space-between"
37888
38566
  }
37889
38567
  },
37890
- /* @__PURE__ */ import_react9.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: 0 } }, /* @__PURE__ */ import_react9.default.createElement(
38568
+ /* @__PURE__ */ import_react11.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: 0 } }, /* @__PURE__ */ import_react11.default.createElement(
37891
38569
  "img",
37892
38570
  {
37893
38571
  src: "https://dashboard.cuekit.ai/_next/image?url=%2Fimages%2Fcuekit-logo-2.png&w=256&q=100",
37894
38572
  alt: "Cuekit AI",
37895
38573
  style: { width: 58, objectFit: "cover" }
37896
38574
  }
37897
- ), /* @__PURE__ */ import_react9.default.createElement(
38575
+ ), /* @__PURE__ */ import_react11.default.createElement(
37898
38576
  "div",
37899
38577
  {
37900
38578
  style: {
@@ -37905,7 +38583,7 @@ var ChatPopup = ({
37905
38583
  justifyContent: "center"
37906
38584
  }
37907
38585
  },
37908
- /* @__PURE__ */ import_react9.default.createElement(
38586
+ /* @__PURE__ */ import_react11.default.createElement(
37909
38587
  "span",
37910
38588
  {
37911
38589
  style: {
@@ -37920,9 +38598,9 @@ var ChatPopup = ({
37920
38598
  WebkitTextFillColor: "transparent"
37921
38599
  }
37922
38600
  },
37923
- "Cuekit.ai"
38601
+ "ansyr.ai"
37924
38602
  ),
37925
- /* @__PURE__ */ import_react9.default.createElement("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 4 } }, /* @__PURE__ */ import_react9.default.createElement(
38603
+ /* @__PURE__ */ import_react11.default.createElement("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 4 } }, /* @__PURE__ */ import_react11.default.createElement(
37926
38604
  "div",
37927
38605
  {
37928
38606
  style: {
@@ -37938,7 +38616,7 @@ var ChatPopup = ({
37938
38616
  fontWeight: "500"
37939
38617
  }
37940
38618
  },
37941
- /* @__PURE__ */ import_react9.default.createElement(
38619
+ /* @__PURE__ */ import_react11.default.createElement(
37942
38620
  "span",
37943
38621
  {
37944
38622
  style: {
@@ -37949,8 +38627,8 @@ var ChatPopup = ({
37949
38627
  )
37950
38628
  ))
37951
38629
  )),
37952
- /* @__PURE__ */ import_react9.default.createElement("div", { style: { minWidth: 100, textAlign: "center" } }),
37953
- /* @__PURE__ */ import_react9.default.createElement(
38630
+ /* @__PURE__ */ import_react11.default.createElement("div", { style: { minWidth: 100, textAlign: "center" } }),
38631
+ /* @__PURE__ */ import_react11.default.createElement(
37954
38632
  "div",
37955
38633
  {
37956
38634
  style: {
@@ -37962,7 +38640,7 @@ var ChatPopup = ({
37962
38640
  top: 16
37963
38641
  }
37964
38642
  },
37965
- onThemeToggle && /* @__PURE__ */ import_react9.default.createElement(
38643
+ onThemeToggle && /* @__PURE__ */ import_react11.default.createElement(
37966
38644
  "button",
37967
38645
  {
37968
38646
  onClick: () => {
@@ -37992,7 +38670,7 @@ var ChatPopup = ({
37992
38670
  "aria-label": "Toggle theme",
37993
38671
  title: `Switch to ${currentTheme === "dark" ? "light" : "dark"} mode`
37994
38672
  },
37995
- currentTheme === "dark" ? /* @__PURE__ */ import_react9.default.createElement(
38673
+ currentTheme === "dark" ? /* @__PURE__ */ import_react11.default.createElement(
37996
38674
  sun_default,
37997
38675
  {
37998
38676
  style: {
@@ -38002,7 +38680,7 @@ var ChatPopup = ({
38002
38680
  animation: "themeToggleEnter 0.3s ease-in-out"
38003
38681
  }
38004
38682
  }
38005
- ) : /* @__PURE__ */ import_react9.default.createElement(
38683
+ ) : /* @__PURE__ */ import_react11.default.createElement(
38006
38684
  moon_default,
38007
38685
  {
38008
38686
  style: {
@@ -38014,7 +38692,7 @@ var ChatPopup = ({
38014
38692
  }
38015
38693
  )
38016
38694
  ),
38017
- /* @__PURE__ */ import_react9.default.createElement(
38695
+ /* @__PURE__ */ import_react11.default.createElement(
38018
38696
  "button",
38019
38697
  {
38020
38698
  onClick: onMinimize,
@@ -38041,11 +38719,11 @@ var ChatPopup = ({
38041
38719
  "aria-label": "Minimize",
38042
38720
  title: "Minimize chat"
38043
38721
  },
38044
- /* @__PURE__ */ import_react9.default.createElement(close_default, { style: { width: 16, height: 16, color: "hsl(var(--voice-text-muted))" } })
38722
+ /* @__PURE__ */ import_react11.default.createElement(close_default, { style: { width: 16, height: 16, color: "hsl(var(--voice-text-muted))" } })
38045
38723
  )
38046
38724
  )
38047
38725
  ),
38048
- /* @__PURE__ */ import_react9.default.createElement(
38726
+ /* @__PURE__ */ import_react11.default.createElement(
38049
38727
  "div",
38050
38728
  {
38051
38729
  style: {
@@ -38058,7 +38736,7 @@ var ChatPopup = ({
38058
38736
  color: "hsl(var(--voice-text))"
38059
38737
  }
38060
38738
  },
38061
- messages.length === 0 ? /* @__PURE__ */ import_react9.default.createElement(
38739
+ messages.length === 0 ? /* @__PURE__ */ import_react11.default.createElement(
38062
38740
  "div",
38063
38741
  {
38064
38742
  style: {
@@ -38068,7 +38746,7 @@ var ChatPopup = ({
38068
38746
  }
38069
38747
  },
38070
38748
  "Start a conversation with CueKit AI"
38071
- ) : messages.map((message, index2) => /* @__PURE__ */ import_react9.default.createElement(
38749
+ ) : messages.map((message, index2) => /* @__PURE__ */ import_react11.default.createElement(
38072
38750
  "div",
38073
38751
  {
38074
38752
  key: index2,
@@ -38082,7 +38760,7 @@ var ChatPopup = ({
38082
38760
  justifyContent: message.sender === "user" ? "flex-end" : "flex-start"
38083
38761
  }
38084
38762
  },
38085
- message.sender === "assistant" && /* @__PURE__ */ import_react9.default.createElement(
38763
+ message.sender === "assistant" && /* @__PURE__ */ import_react11.default.createElement(
38086
38764
  "div",
38087
38765
  {
38088
38766
  style: {
@@ -38097,7 +38775,7 @@ var ChatPopup = ({
38097
38775
  overflow: "hidden"
38098
38776
  }
38099
38777
  },
38100
- /* @__PURE__ */ import_react9.default.createElement(
38778
+ /* @__PURE__ */ import_react11.default.createElement(
38101
38779
  "img",
38102
38780
  {
38103
38781
  src: "https://dashboard.cuekit.ai/_next/image?url=%2Fimages%2Fcuekit-logo-2.png&w=256&q=100",
@@ -38111,7 +38789,7 @@ var ChatPopup = ({
38111
38789
  }
38112
38790
  )
38113
38791
  ),
38114
- /* @__PURE__ */ import_react9.default.createElement(
38792
+ /* @__PURE__ */ import_react11.default.createElement(
38115
38793
  "div",
38116
38794
  {
38117
38795
  style: {
@@ -38122,7 +38800,7 @@ var ChatPopup = ({
38122
38800
  flex: 1
38123
38801
  }
38124
38802
  },
38125
- /* @__PURE__ */ import_react9.default.createElement(
38803
+ /* @__PURE__ */ import_react11.default.createElement(
38126
38804
  "div",
38127
38805
  {
38128
38806
  style: {
@@ -38140,12 +38818,12 @@ var ChatPopup = ({
38140
38818
  marginLeft: message.sender === "user" ? "auto" : 0
38141
38819
  }
38142
38820
  },
38143
- /* @__PURE__ */ import_react9.default.createElement("div", null, /* @__PURE__ */ import_react9.default.createElement(
38821
+ /* @__PURE__ */ import_react11.default.createElement("div", null, /* @__PURE__ */ import_react11.default.createElement(
38144
38822
  Markdown,
38145
38823
  {
38146
38824
  remarkPlugins: [remarkGfm],
38147
38825
  components: {
38148
- p: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
38826
+ p: ({ children }) => /* @__PURE__ */ import_react11.default.createElement(
38149
38827
  "p",
38150
38828
  {
38151
38829
  style: {
@@ -38156,7 +38834,7 @@ var ChatPopup = ({
38156
38834
  },
38157
38835
  children
38158
38836
  ),
38159
- h1: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
38837
+ h1: ({ children }) => /* @__PURE__ */ import_react11.default.createElement(
38160
38838
  "h1",
38161
38839
  {
38162
38840
  style: {
@@ -38168,7 +38846,7 @@ var ChatPopup = ({
38168
38846
  },
38169
38847
  children
38170
38848
  ),
38171
- h2: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
38849
+ h2: ({ children }) => /* @__PURE__ */ import_react11.default.createElement(
38172
38850
  "h2",
38173
38851
  {
38174
38852
  style: {
@@ -38180,7 +38858,7 @@ var ChatPopup = ({
38180
38858
  },
38181
38859
  children
38182
38860
  ),
38183
- h3: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
38861
+ h3: ({ children }) => /* @__PURE__ */ import_react11.default.createElement(
38184
38862
  "h3",
38185
38863
  {
38186
38864
  style: {
@@ -38192,7 +38870,7 @@ var ChatPopup = ({
38192
38870
  },
38193
38871
  children
38194
38872
  ),
38195
- ul: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
38873
+ ul: ({ children }) => /* @__PURE__ */ import_react11.default.createElement(
38196
38874
  "ul",
38197
38875
  {
38198
38876
  style: {
@@ -38204,7 +38882,7 @@ var ChatPopup = ({
38204
38882
  },
38205
38883
  children
38206
38884
  ),
38207
- ol: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
38885
+ ol: ({ children }) => /* @__PURE__ */ import_react11.default.createElement(
38208
38886
  "ol",
38209
38887
  {
38210
38888
  style: {
@@ -38216,7 +38894,7 @@ var ChatPopup = ({
38216
38894
  },
38217
38895
  children
38218
38896
  ),
38219
- li: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
38897
+ li: ({ children }) => /* @__PURE__ */ import_react11.default.createElement(
38220
38898
  "li",
38221
38899
  {
38222
38900
  style: {
@@ -38227,7 +38905,7 @@ var ChatPopup = ({
38227
38905
  },
38228
38906
  children
38229
38907
  ),
38230
- strong: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
38908
+ strong: ({ children }) => /* @__PURE__ */ import_react11.default.createElement(
38231
38909
  "strong",
38232
38910
  {
38233
38911
  style: {
@@ -38238,7 +38916,7 @@ var ChatPopup = ({
38238
38916
  },
38239
38917
  children
38240
38918
  ),
38241
- em: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
38919
+ em: ({ children }) => /* @__PURE__ */ import_react11.default.createElement(
38242
38920
  "em",
38243
38921
  {
38244
38922
  style: {
@@ -38249,7 +38927,7 @@ var ChatPopup = ({
38249
38927
  },
38250
38928
  children
38251
38929
  ),
38252
- code: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
38930
+ code: ({ children }) => /* @__PURE__ */ import_react11.default.createElement(
38253
38931
  "code",
38254
38932
  {
38255
38933
  style: {
@@ -38262,7 +38940,7 @@ var ChatPopup = ({
38262
38940
  },
38263
38941
  children
38264
38942
  ),
38265
- pre: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
38943
+ pre: ({ children }) => /* @__PURE__ */ import_react11.default.createElement(
38266
38944
  "pre",
38267
38945
  {
38268
38946
  style: {
@@ -38277,7 +38955,7 @@ var ChatPopup = ({
38277
38955
  },
38278
38956
  children
38279
38957
  ),
38280
- blockquote: ({ children }) => /* @__PURE__ */ import_react9.default.createElement(
38958
+ blockquote: ({ children }) => /* @__PURE__ */ import_react11.default.createElement(
38281
38959
  "blockquote",
38282
38960
  {
38283
38961
  style: {
@@ -38296,7 +38974,7 @@ var ChatPopup = ({
38296
38974
  message.text
38297
38975
  ))
38298
38976
  ),
38299
- message.sender === "user" && /* @__PURE__ */ import_react9.default.createElement(
38977
+ message.sender === "user" && /* @__PURE__ */ import_react11.default.createElement(
38300
38978
  "div",
38301
38979
  {
38302
38980
  style: {
@@ -38317,9 +38995,9 @@ var ChatPopup = ({
38317
38995
  )
38318
38996
  )
38319
38997
  )),
38320
- /* @__PURE__ */ import_react9.default.createElement("div", { ref: messagesEndRef })
38998
+ /* @__PURE__ */ import_react11.default.createElement("div", { ref: messagesEndRef })
38321
38999
  ),
38322
- /* @__PURE__ */ import_react9.default.createElement(
39000
+ /* @__PURE__ */ import_react11.default.createElement(
38323
39001
  "div",
38324
39002
  {
38325
39003
  style: {
@@ -38328,7 +39006,7 @@ var ChatPopup = ({
38328
39006
  background: "hsl(var(--voice-bg))"
38329
39007
  }
38330
39008
  },
38331
- /* @__PURE__ */ import_react9.default.createElement(
39009
+ /* @__PURE__ */ import_react11.default.createElement(
38332
39010
  "form",
38333
39011
  {
38334
39012
  onSubmit: (e3) => {
@@ -38337,7 +39015,7 @@ var ChatPopup = ({
38337
39015
  },
38338
39016
  style: { display: "flex", alignItems: "center", gap: 8, margin: 0 }
38339
39017
  },
38340
- /* @__PURE__ */ import_react9.default.createElement(
39018
+ /* @__PURE__ */ import_react11.default.createElement(
38341
39019
  "input",
38342
39020
  {
38343
39021
  type: "text",
@@ -38364,7 +39042,47 @@ var ChatPopup = ({
38364
39042
  }
38365
39043
  }
38366
39044
  ),
38367
- isConnected2 && onEndCall && /* @__PURE__ */ import_react9.default.createElement(
39045
+ muteState?.canMute && onToggleMute && /* @__PURE__ */ import_react11.default.createElement(
39046
+ "button",
39047
+ {
39048
+ onClick: onToggleMute,
39049
+ style: {
39050
+ padding: "10px 12px",
39051
+ borderRadius: 8,
39052
+ border: "1px solid hsl(var(--voice-accent))",
39053
+ background: "hsl(var(--voice-accent))",
39054
+ fontSize: 12,
39055
+ fontWeight: 700,
39056
+ display: "flex",
39057
+ alignItems: "center",
39058
+ justifyContent: "center",
39059
+ cursor: "pointer",
39060
+ transition: "all 0.3s ease"
39061
+ },
39062
+ "aria-label": muteState.isMuted ? "Unmute microphone" : "Mute microphone",
39063
+ title: muteState.isMuted ? "Unmute microphone" : "Mute microphone"
39064
+ },
39065
+ muteState.isMuted ? /* @__PURE__ */ import_react11.default.createElement(
39066
+ mic_default,
39067
+ {
39068
+ style: {
39069
+ width: 16,
39070
+ height: 16,
39071
+ color: "hsl(var(--voice-user-text))"
39072
+ }
39073
+ }
39074
+ ) : /* @__PURE__ */ import_react11.default.createElement(
39075
+ mic_off_default,
39076
+ {
39077
+ style: {
39078
+ width: 16,
39079
+ height: 16,
39080
+ color: "hsl(var(--voice-user-text))"
39081
+ }
39082
+ }
39083
+ )
39084
+ ),
39085
+ isConnected2 && onEndCall && /* @__PURE__ */ import_react11.default.createElement(
38368
39086
  "button",
38369
39087
  {
38370
39088
  type: "submit",
@@ -38383,7 +39101,7 @@ var ChatPopup = ({
38383
39101
  cursor: "pointer"
38384
39102
  }
38385
39103
  },
38386
- /* @__PURE__ */ import_react9.default.createElement(phone_off_default, { style: { width: 16, height: 16 } })
39104
+ /* @__PURE__ */ import_react11.default.createElement(phone_off_default, { style: { width: 16, height: 16 } })
38387
39105
  )
38388
39106
  )
38389
39107
  )
@@ -38391,7 +39109,7 @@ var ChatPopup = ({
38391
39109
  };
38392
39110
 
38393
39111
  // src/components/border-glow.tsx
38394
- var import_react10 = __toESM(require("react"));
39112
+ var import_react12 = __toESM(require("react"));
38395
39113
  var BorderGlow = ({ isActive }) => {
38396
39114
  if (!isActive) return null;
38397
39115
  const styles = {
@@ -38518,7 +39236,7 @@ var BorderGlow = ({ isActive }) => {
38518
39236
  opacity: 0.6
38519
39237
  }
38520
39238
  };
38521
- return /* @__PURE__ */ import_react10.default.createElement(import_react10.default.Fragment, null, /* @__PURE__ */ import_react10.default.createElement("style", null, `
39239
+ return /* @__PURE__ */ import_react12.default.createElement(import_react12.default.Fragment, null, /* @__PURE__ */ import_react12.default.createElement("style", null, `
38522
39240
  @keyframes borderPulse {
38523
39241
  0%, 100% {
38524
39242
  opacity: 1;
@@ -38527,12 +39245,12 @@ var BorderGlow = ({ isActive }) => {
38527
39245
  opacity: 0.5;
38528
39246
  }
38529
39247
  }
38530
- `), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.container }, /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.rightBorder1 }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.rightBorder2 }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.rightBorder3 }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.leftBorder1 }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.leftBorder2 }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.leftBorder3 }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.cornerTopLeft }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.cornerTopRight }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.cornerBottomRight }), /* @__PURE__ */ import_react10.default.createElement("div", { style: styles.cornerBottomLeft })));
39248
+ `), /* @__PURE__ */ import_react12.default.createElement("div", { style: styles.container }, /* @__PURE__ */ import_react12.default.createElement("div", { style: styles.rightBorder1 }), /* @__PURE__ */ import_react12.default.createElement("div", { style: styles.rightBorder2 }), /* @__PURE__ */ import_react12.default.createElement("div", { style: styles.rightBorder3 }), /* @__PURE__ */ import_react12.default.createElement("div", { style: styles.leftBorder1 }), /* @__PURE__ */ import_react12.default.createElement("div", { style: styles.leftBorder2 }), /* @__PURE__ */ import_react12.default.createElement("div", { style: styles.leftBorder3 }), /* @__PURE__ */ import_react12.default.createElement("div", { style: styles.cornerTopLeft }), /* @__PURE__ */ import_react12.default.createElement("div", { style: styles.cornerTopRight }), /* @__PURE__ */ import_react12.default.createElement("div", { style: styles.cornerBottomRight }), /* @__PURE__ */ import_react12.default.createElement("div", { style: styles.cornerBottomLeft })));
38531
39249
  };
38532
39250
  var border_glow_default = BorderGlow;
38533
39251
 
38534
39252
  // src/components/voice-intensity-visualizer.tsx
38535
- var import_react12 = __toESM(require("react"));
39253
+ var import_react14 = __toESM(require("react"));
38536
39254
 
38537
39255
  // node_modules/@livekit/components-react/dist/hooks-C2Bp5v2q.mjs
38538
39256
  var r2 = __toESM(require("react"), 1);
@@ -38548,7 +39266,7 @@ var Me = { exports: {} };
38548
39266
  var Or = Me.exports;
38549
39267
  var kt;
38550
39268
  function kr() {
38551
- return kt || (kt = 1, function(e3) {
39269
+ return kt || (kt = 1, (function(e3) {
38552
39270
  (function(t, n) {
38553
39271
  e3.exports ? e3.exports = n() : t.log = n();
38554
39272
  })(Or, function() {
@@ -38692,7 +39410,7 @@ function kr() {
38692
39410
  return o2;
38693
39411
  }, s.default = s, s;
38694
39412
  });
38695
- }(Me)), Me.exports;
39413
+ })(Me)), Me.exports;
38696
39414
  }
38697
39415
  var _r = kr();
38698
39416
  var Lr = /* @__PURE__ */ Ar(_r);
@@ -38915,7 +39633,7 @@ function Ue(e3, t) {
38915
39633
  0 <= n && e3.splice(n, 1);
38916
39634
  }
38917
39635
  }
38918
- var Oe = function() {
39636
+ var Oe = (function() {
38919
39637
  function e3(t) {
38920
39638
  this.initialTeardown = t, this.closed = false, this._parentage = null, this._finalizers = null;
38921
39639
  }
@@ -38999,11 +39717,11 @@ var Oe = function() {
38999
39717
  }, e3.prototype.remove = function(t) {
39000
39718
  var n = this._finalizers;
39001
39719
  n && Ue(n, t), t instanceof e3 && t._removeParent(this);
39002
- }, e3.EMPTY = function() {
39720
+ }, e3.EMPTY = (function() {
39003
39721
  var t = new e3();
39004
39722
  return t.closed = true, t;
39005
- }(), e3;
39006
- }();
39723
+ })(), e3;
39724
+ })();
39007
39725
  var an = Oe.EMPTY;
39008
39726
  function cn(e3) {
39009
39727
  return e3 instanceof Oe || e3 && "closed" in e3 && P(e3.remove) && P(e3.add) && P(e3.unsubscribe);
@@ -39035,7 +39753,7 @@ function je() {
39035
39753
  function Re(e3) {
39036
39754
  e3();
39037
39755
  }
39038
- var gt = function(e3) {
39756
+ var gt = (function(e3) {
39039
39757
  te(t, e3);
39040
39758
  function t(n) {
39041
39759
  var r3 = e3.call(this) || this;
@@ -39066,8 +39784,8 @@ var gt = function(e3) {
39066
39784
  this.unsubscribe();
39067
39785
  }
39068
39786
  }, t;
39069
- }(Oe);
39070
- var Nr = function() {
39787
+ })(Oe);
39788
+ var Nr = (function() {
39071
39789
  function e3(t) {
39072
39790
  this.partialObserver = t;
39073
39791
  }
@@ -39098,8 +39816,8 @@ var Nr = function() {
39098
39816
  Le(n);
39099
39817
  }
39100
39818
  }, e3;
39101
- }();
39102
- var Ce = function(e3) {
39819
+ })();
39820
+ var Ce = (function(e3) {
39103
39821
  te(t, e3);
39104
39822
  function t(n, r3, i2) {
39105
39823
  var o2 = e3.call(this) || this, s;
@@ -39110,7 +39828,7 @@ var Ce = function(e3) {
39110
39828
  } : s = n, o2.destination = new Nr(s), o2;
39111
39829
  }
39112
39830
  return t;
39113
- }(gt);
39831
+ })(gt);
39114
39832
  function Le(e3) {
39115
39833
  un(e3);
39116
39834
  }
@@ -39123,9 +39841,9 @@ var Ur = {
39123
39841
  error: Fr,
39124
39842
  complete: je
39125
39843
  };
39126
- var bt = function() {
39844
+ var bt = (function() {
39127
39845
  return typeof Symbol == "function" && Symbol.observable || "@@observable";
39128
- }();
39846
+ })();
39129
39847
  function Ge(e3) {
39130
39848
  return e3;
39131
39849
  }
@@ -39136,7 +39854,7 @@ function jr(e3) {
39136
39854
  }, n);
39137
39855
  };
39138
39856
  }
39139
- var k = function() {
39857
+ var k = (function() {
39140
39858
  function e3(t) {
39141
39859
  t && (this._subscribe = t);
39142
39860
  }
@@ -39195,7 +39913,7 @@ var k = function() {
39195
39913
  }, e3.create = function(t) {
39196
39914
  return new e3(t);
39197
39915
  }, e3;
39198
- }();
39916
+ })();
39199
39917
  function Lt(e3) {
39200
39918
  var t;
39201
39919
  return (t = e3 ?? Dr.Promise) !== null && t !== void 0 ? t : Promise;
@@ -39225,7 +39943,7 @@ function j(e3) {
39225
39943
  function F(e3, t, n, r3, i2) {
39226
39944
  return new Hr(e3, t, n, r3, i2);
39227
39945
  }
39228
- var Hr = function(e3) {
39946
+ var Hr = (function(e3) {
39229
39947
  te(t, e3);
39230
39948
  function t(n, r3, i2, o2, s, a) {
39231
39949
  var c = e3.call(this, n) || this;
@@ -39260,13 +39978,13 @@ var Hr = function(e3) {
39260
39978
  e3.prototype.unsubscribe.call(this), !r3 && ((n = this.onFinalize) === null || n === void 0 || n.call(this));
39261
39979
  }
39262
39980
  }, t;
39263
- }(gt);
39981
+ })(gt);
39264
39982
  var zr = mt(function(e3) {
39265
39983
  return function() {
39266
39984
  e3(this), this.name = "ObjectUnsubscribedError", this.message = "object unsubscribed";
39267
39985
  };
39268
39986
  });
39269
- var ee = function(e3) {
39987
+ var ee = (function(e3) {
39270
39988
  te(t, e3);
39271
39989
  function t() {
39272
39990
  var n = e3.call(this) || this;
@@ -39345,8 +40063,8 @@ var ee = function(e3) {
39345
40063
  }, t.create = function(n, r3) {
39346
40064
  return new It(n, r3);
39347
40065
  }, t;
39348
- }(k);
39349
- var It = function(e3) {
40066
+ })(k);
40067
+ var It = (function(e3) {
39350
40068
  te(t, e3);
39351
40069
  function t(n, r3) {
39352
40070
  var i2 = e3.call(this) || this;
@@ -39365,8 +40083,8 @@ var It = function(e3) {
39365
40083
  var r3, i2;
39366
40084
  return (i2 = (r3 = this.source) === null || r3 === void 0 ? void 0 : r3.subscribe(n)) !== null && i2 !== void 0 ? i2 : an;
39367
40085
  }, t;
39368
- }(ee);
39369
- var ln = function(e3) {
40086
+ })(ee);
40087
+ var ln = (function(e3) {
39370
40088
  te(t, e3);
39371
40089
  function t(n) {
39372
40090
  var r3 = e3.call(this) || this;
@@ -39389,13 +40107,13 @@ var ln = function(e3) {
39389
40107
  }, t.prototype.next = function(n) {
39390
40108
  e3.prototype.next.call(this, this._value = n);
39391
40109
  }, t;
39392
- }(ee);
40110
+ })(ee);
39393
40111
  var Yr = {
39394
40112
  now: function() {
39395
40113
  return Date.now();
39396
40114
  }
39397
40115
  };
39398
- var qr = function(e3) {
40116
+ var qr = (function(e3) {
39399
40117
  te(t, e3);
39400
40118
  function t(n, r3) {
39401
40119
  return e3.call(this) || this;
@@ -39403,7 +40121,7 @@ var qr = function(e3) {
39403
40121
  return t.prototype.schedule = function(n, r3) {
39404
40122
  return this;
39405
40123
  }, t;
39406
- }(Oe);
40124
+ })(Oe);
39407
40125
  var Mt = {
39408
40126
  setInterval: function(e3, t) {
39409
40127
  for (var n = [], r3 = 2; r3 < arguments.length; r3++)
@@ -39415,7 +40133,7 @@ var Mt = {
39415
40133
  },
39416
40134
  delegate: void 0
39417
40135
  };
39418
- var Kr = function(e3) {
40136
+ var Kr = (function(e3) {
39419
40137
  te(t, e3);
39420
40138
  function t(n, r3) {
39421
40139
  var i2 = e3.call(this, n, r3) || this;
@@ -39457,16 +40175,16 @@ var Kr = function(e3) {
39457
40175
  this.work = this.state = this.scheduler = null, this.pending = false, Ue(o2, this), r3 != null && (this.id = this.recycleAsyncId(i2, r3, null)), this.delay = null, e3.prototype.unsubscribe.call(this);
39458
40176
  }
39459
40177
  }, t;
39460
- }(qr);
39461
- var Rt = function() {
40178
+ })(qr);
40179
+ var Rt = (function() {
39462
40180
  function e3(t, n) {
39463
40181
  n === void 0 && (n = e3.now), this.schedulerActionCtor = t, this.now = n;
39464
40182
  }
39465
40183
  return e3.prototype.schedule = function(t, n, r3) {
39466
40184
  return n === void 0 && (n = 0), new this.schedulerActionCtor(this, t).schedule(r3, n);
39467
40185
  }, e3.now = Yr.now, e3;
39468
- }();
39469
- var Gr = function(e3) {
40186
+ })();
40187
+ var Gr = (function(e3) {
39470
40188
  te(t, e3);
39471
40189
  function t(n, r3) {
39472
40190
  r3 === void 0 && (r3 = Rt.now);
@@ -39491,7 +40209,7 @@ var Gr = function(e3) {
39491
40209
  throw i2;
39492
40210
  }
39493
40211
  }, t;
39494
- }(Rt);
40212
+ })(Rt);
39495
40213
  var Qr = new Gr(Kr);
39496
40214
  function Jr(e3) {
39497
40215
  return e3 && P(e3.schedule);
@@ -40178,7 +40896,7 @@ function Yt(e3, t = {}) {
40178
40896
 
40179
40897
  // node_modules/@livekit/components-react/dist/components-Bz2b1Fa9.mjs
40180
40898
  var e2 = __toESM(require("react"), 1);
40181
- var import_react11 = require("react");
40899
+ var import_react13 = require("react");
40182
40900
  init_livekit_client_esm();
40183
40901
  var Y;
40184
40902
  var ue;
@@ -40273,8 +40991,8 @@ var Dt = (t) => {
40273
40991
  };
40274
40992
  var fe2 = (t) => [[Math.floor(t / 2)], [-1]];
40275
40993
  var Ut2 = (t, n, a) => {
40276
- const [r3, c] = (0, import_react11.useState)(0), [s, o2] = (0, import_react11.useState)([[]]);
40277
- (0, import_react11.useEffect)(() => {
40994
+ const [r3, c] = (0, import_react13.useState)(0), [s, o2] = (0, import_react13.useState)([[]]);
40995
+ (0, import_react13.useEffect)(() => {
40278
40996
  if (t === "thinking")
40279
40997
  o2(fe2(n));
40280
40998
  else if (t === "connecting" || t === "initializing") {
@@ -40283,8 +41001,8 @@ var Ut2 = (t, n, a) => {
40283
41001
  } else o2(t === "listening" ? fe2(n) : t === void 0 || t === "speaking" ? [new Array(n).fill(0).map((i2, u) => u)] : [[]]);
40284
41002
  c(0);
40285
41003
  }, [t, n]);
40286
- const l = (0, import_react11.useRef)(null);
40287
- return (0, import_react11.useEffect)(() => {
41004
+ const l = (0, import_react13.useRef)(null);
41005
+ return (0, import_react13.useEffect)(() => {
40288
41006
  let i2 = performance.now();
40289
41007
  const u = (d) => {
40290
41008
  d - i2 >= a && (c((f) => f + 1), i2 = d), l.current = requestAnimationFrame(u);
@@ -40354,8 +41072,8 @@ var Xt = /* @__PURE__ */ e2.forwardRef(
40354
41072
  init_livekit_client_esm();
40355
41073
  init_webrtc_service();
40356
41074
  var VoiceIntensityWithRoom = (props) => {
40357
- const [room2, setRoom] = (0, import_react12.useState)(null);
40358
- (0, import_react12.useEffect)(() => {
41075
+ const [room2, setRoom] = (0, import_react14.useState)(null);
41076
+ (0, import_react14.useEffect)(() => {
40359
41077
  if (props.isActive) {
40360
41078
  const currentRoom = getRoom();
40361
41079
  if (currentRoom) {
@@ -40368,7 +41086,7 @@ var VoiceIntensityWithRoom = (props) => {
40368
41086
  if (!room2) {
40369
41087
  return null;
40370
41088
  }
40371
- return /* @__PURE__ */ import_react12.default.createElement(Wn.Provider, { value: room2 }, /* @__PURE__ */ import_react12.default.createElement(VoiceIntensityBars, { ...props }));
41089
+ return /* @__PURE__ */ import_react14.default.createElement(Wn.Provider, { value: room2 }, /* @__PURE__ */ import_react14.default.createElement(VoiceIntensityBars, { ...props }));
40372
41090
  };
40373
41091
  var VoiceIntensityBars = ({
40374
41092
  isActive,
@@ -40411,7 +41129,7 @@ var VoiceIntensityBars = ({
40411
41129
  if (!trackRef) {
40412
41130
  return null;
40413
41131
  }
40414
- return /* @__PURE__ */ import_react12.default.createElement(
41132
+ return /* @__PURE__ */ import_react14.default.createElement(
40415
41133
  "div",
40416
41134
  {
40417
41135
  className: `voice-intensity-visualizer ${className}`,
@@ -40428,7 +41146,7 @@ var VoiceIntensityBars = ({
40428
41146
  pointerEvents: "none"
40429
41147
  }
40430
41148
  },
40431
- /* @__PURE__ */ import_react12.default.createElement(
41149
+ /* @__PURE__ */ import_react14.default.createElement(
40432
41150
  Xt,
40433
41151
  {
40434
41152
  barCount,
@@ -40442,7 +41160,7 @@ var VoiceIntensityBars = ({
40442
41160
  gap: "0.25rem"
40443
41161
  }
40444
41162
  },
40445
- /* @__PURE__ */ import_react12.default.createElement("span", { className: "cuekit-voice-intensity-bar" })
41163
+ /* @__PURE__ */ import_react14.default.createElement("span", { className: "cuekit-voice-intensity-bar" })
40446
41164
  )
40447
41165
  );
40448
41166
  };
@@ -40450,56 +41168,6 @@ var VoiceIntensityVisualizer = VoiceIntensityWithRoom;
40450
41168
 
40451
41169
  // src/components/mic-button.tsx
40452
41170
  init_webrtc_service();
40453
-
40454
- // src/components/svgs/mic.tsx
40455
- var import_react13 = __toESM(require("react"));
40456
- var MicIcon = ({ width = 24, height = 24, className, ...props }) => {
40457
- return /* @__PURE__ */ import_react13.default.createElement(
40458
- "svg",
40459
- {
40460
- xmlns: "http://www.w3.org/2000/svg",
40461
- width,
40462
- height,
40463
- viewBox: "0 0 24 24",
40464
- fill: "none",
40465
- stroke: "currentColor",
40466
- strokeWidth: "2",
40467
- strokeLinecap: "round",
40468
- strokeLinejoin: "round",
40469
- className,
40470
- ...props
40471
- },
40472
- /* @__PURE__ */ import_react13.default.createElement("path", { d: "M12 19v3" }),
40473
- /* @__PURE__ */ import_react13.default.createElement("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
40474
- /* @__PURE__ */ import_react13.default.createElement("rect", { x: "9", y: "2", width: "6", height: "13", rx: "3" })
40475
- );
40476
- };
40477
- var mic_default = MicIcon;
40478
-
40479
- // src/components/svgs/loader.tsx
40480
- var import_react14 = __toESM(require("react"));
40481
- var LoaderIcon = ({ width = 24, height = 24, className, ...props }) => {
40482
- return /* @__PURE__ */ import_react14.default.createElement(
40483
- "svg",
40484
- {
40485
- xmlns: "http://www.w3.org/2000/svg",
40486
- width: "24",
40487
- height: "24",
40488
- viewBox: "0 0 24 24",
40489
- fill: "none",
40490
- stroke: "currentColor",
40491
- strokeWidth: "2",
40492
- strokeLinecap: "round",
40493
- strokeLinejoin: "round",
40494
- className,
40495
- ...props
40496
- },
40497
- /* @__PURE__ */ import_react14.default.createElement("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
40498
- );
40499
- };
40500
- var loader_default = LoaderIcon;
40501
-
40502
- // src/components/mic-button.tsx
40503
41171
  var chatState = {
40504
41172
  isOpen: false,
40505
41173
  isMinimized: false
@@ -40549,16 +41217,18 @@ var MicButton = ({
40549
41217
  connect: voiceConnect,
40550
41218
  disconnect: voiceDisconnect,
40551
41219
  sendUserCommand: sendUserCommand2,
41220
+ sendChatMessage,
40552
41221
  messages: messageManagerMessages,
40553
41222
  micState,
40554
41223
  setMicState,
40555
41224
  status,
40556
41225
  setStatus,
40557
- participants
41226
+ participants,
41227
+ muteState,
41228
+ toggleMute,
41229
+ setMute
40558
41230
  } = useCuekit({
40559
- onNavigationCommand: (command) => {
40560
- console.log("\u{1F3A4} MicButton: Navigation command received:", command);
40561
- },
41231
+ // Don't override navigation command - let the provider handle it
40562
41232
  onConnectionStateChange: (state) => {
40563
41233
  console.log("\u{1F3A4} MicButton: Connection state changed:", state);
40564
41234
  },
@@ -40703,7 +41373,9 @@ var MicButton = ({
40703
41373
  apiKey,
40704
41374
  appId,
40705
41375
  openChat,
40706
- showBorderGlow
41376
+ showBorderGlow,
41377
+ sendChatMessage,
41378
+ isChatOpen
40707
41379
  ]);
40708
41380
  const handleSendText = async (textToSend) => {
40709
41381
  setMicState("thinking");
@@ -40713,13 +41385,14 @@ var MicButton = ({
40713
41385
  }
40714
41386
  if (isConnected2) {
40715
41387
  try {
40716
- await sendUserCommand2(textToSend);
41388
+ await sendChatMessage(textToSend);
40717
41389
  setMicState("replying");
40718
41390
  setTimeout(() => {
40719
41391
  setMicState("listening");
40720
41392
  if (showBorderGlow) setShowBodyGlow(true);
40721
41393
  }, 1e3);
40722
41394
  } catch (error) {
41395
+ console.error("Failed to send chat message:", error);
40723
41396
  } finally {
40724
41397
  setMicState("listening");
40725
41398
  if (showBorderGlow) setShowBodyGlow(true);
@@ -40746,8 +41419,11 @@ var MicButton = ({
40746
41419
  filter: "drop-shadow(0 10px 8px rgba(0, 0, 0, 0.04)) drop-shadow(0 4px 3px rgba(0, 0, 0, 0.1))",
40747
41420
  ...imageStyle
40748
41421
  };
40749
- const animatedImageStyle = micState === "thinking" ? { ...baseImageStyle, animation: "spin 1s linear infinite" } : micState === "replying" ? { ...baseImageStyle, animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite" } : baseImageStyle;
40750
- return /* @__PURE__ */ import_react15.default.createElement("img", { src: imageSource, alt: "Voice Assistant", style: animatedImageStyle });
41422
+ if (micState === "idle") {
41423
+ return /* @__PURE__ */ import_react15.default.createElement("img", { src: imageSource, alt: "Voice Assistant", style: baseImageStyle });
41424
+ } else {
41425
+ return /* @__PURE__ */ import_react15.default.createElement(VoiceIntensityWrapper, { active: true, buttonSize });
41426
+ }
40751
41427
  }
40752
41428
  const iconStyle = {
40753
41429
  width: `100%`,
@@ -40755,15 +41431,10 @@ var MicButton = ({
40755
41431
  color: "white",
40756
41432
  filter: "drop-shadow(0 10px 8px rgba(0, 0, 0, 0.04)) drop-shadow(0 4px 3px rgba(0, 0, 0, 0.1))"
40757
41433
  };
40758
- switch (micState) {
40759
- case "thinking":
40760
- return /* @__PURE__ */ import_react15.default.createElement(loader_default, { style: { ...iconStyle, animation: "spin 1s linear infinite" } });
40761
- case "replying":
40762
- return /* @__PURE__ */ import_react15.default.createElement(VoiceIntensityWrapper, { active: true, buttonSize });
40763
- case "listening":
40764
- return /* @__PURE__ */ import_react15.default.createElement(VoiceIntensityWrapper, { active: true, buttonSize });
40765
- default:
40766
- return /* @__PURE__ */ import_react15.default.createElement(mic_default, { style: iconStyle });
41434
+ if (micState === "idle") {
41435
+ return /* @__PURE__ */ import_react15.default.createElement(mic_default, { style: iconStyle });
41436
+ } else {
41437
+ return /* @__PURE__ */ import_react15.default.createElement(VoiceIntensityWrapper, { active: true, buttonSize });
40767
41438
  }
40768
41439
  };
40769
41440
  const getPositionStyle = () => {
@@ -40831,7 +41502,6 @@ var MicButton = ({
40831
41502
  case "thinking":
40832
41503
  baseStyle.transform = "scale(1.05)";
40833
41504
  baseStyle.boxShadow = "0 20px 25px -5px rgba(196, 132, 252, 0.4)";
40834
- baseStyle.animation = "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite";
40835
41505
  break;
40836
41506
  case "replying":
40837
41507
  baseStyle.transform = "scale(1.05)";
@@ -40908,7 +41578,9 @@ var MicButton = ({
40908
41578
  currentTheme,
40909
41579
  onThemeToggle: setCurrentTheme,
40910
41580
  status: getUserFriendlyStatus(micState, isConnected2 ?? false),
40911
- anchor: { position: screenPosition, bottom: bottomSpace, size: buttonSize }
41581
+ anchor: { position: screenPosition, bottom: bottomSpace, size: buttonSize },
41582
+ muteState,
41583
+ onToggleMute: toggleMute
40912
41584
  }
40913
41585
  ), isChatOpen && isChatMinimized && /* @__PURE__ */ import_react15.default.createElement(
40914
41586
  "button",
@@ -40947,4 +41619,4 @@ function generateDynamicId(routePath, elementIdentifier) {
40947
41619
  }
40948
41620
 
40949
41621
  // src/index.ts
40950
- init_element_service();
41622
+ init_navigation();