@pipecat-ai/daily-transport 0.4.0 → 1.1.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.d.ts CHANGED
@@ -1,25 +1,32 @@
1
- import { DailyCall, DailyFactoryOptions, DailyMediaDeviceInfo } from "@daily-co/daily-js";
2
- import { RTVIClientOptions, RTVIMessage, Tracks, Transport, TransportState } from "@pipecat-ai/client-js";
3
- export interface DailyTransportAuthBundle {
4
- room_url: string;
5
- token: string;
1
+ import { DailyCall, DailyCallOptions, DailyFactoryOptions, DailyMeetingSessionSummary, DailyMediaDeviceInfo } from "@daily-co/daily-js";
2
+ import { PipecatClientOptions, RTVIEventCallbacks, RTVIMessage, Tracks, Transport, TransportState } from "@pipecat-ai/client-js";
3
+ export interface DailyConnectionEndpoint {
4
+ endpoint: string;
5
+ headers?: Headers;
6
+ requestData?: object;
7
+ timeout?: number;
6
8
  }
7
- export interface DailyTransportConstructorOptions {
9
+ export interface DailyTransportConstructorOptions extends DailyFactoryOptions {
8
10
  bufferLocalAudioUntilBotReady?: boolean;
9
- dailyFactoryOptions?: DailyFactoryOptions;
10
11
  }
11
12
  export enum DailyRTVIMessageType {
12
13
  AUDIO_BUFFERING_STARTED = "audio-buffering-started",
13
14
  AUDIO_BUFFERING_STOPPED = "audio-buffering-stopped"
14
15
  }
16
+ export type DailyEventCallbacks = RTVIEventCallbacks & Partial<{
17
+ onAudioBufferingStarted: () => void;
18
+ onAudioBufferingStopped: () => void;
19
+ }>;
15
20
  export class DailyTransport extends Transport {
16
- constructor({ dailyFactoryOptions, bufferLocalAudioUntilBotReady, }?: DailyTransportConstructorOptions);
21
+ protected _callbacks: DailyEventCallbacks;
22
+ constructor(opts?: DailyTransportConstructorOptions);
17
23
  handleUserAudioStream(data: ArrayBuffer): void;
18
24
  _sendAudioBatch(dataBatch: ArrayBuffer[]): void;
19
- initialize(options: RTVIClientOptions, messageHandler: (ev: RTVIMessage) => void): void;
25
+ initialize(options: PipecatClientOptions, messageHandler: (ev: RTVIMessage) => void): void;
20
26
  get dailyCallClient(): DailyCall;
21
27
  get state(): TransportState;
22
28
  private set state(value);
29
+ getSessionInfo(): DailyMeetingSessionSummary;
23
30
  getAllCams(): Promise<DailyMediaDeviceInfo[]>;
24
31
  updateCam(camId: string): void;
25
32
  get selectedCam(): MediaDeviceInfo | Record<string, never>;
@@ -36,11 +43,12 @@ export class DailyTransport extends Transport {
36
43
  enableScreenShare(enable: boolean): void;
37
44
  get isSharingScreen(): boolean;
38
45
  tracks(): Tracks;
39
- preAuth(dailyFactoryOptions: DailyFactoryOptions): Promise<void>;
46
+ preAuth(dailyCallOptions: DailyCallOptions): Promise<void>;
40
47
  initDevices(): Promise<void>;
41
- connect(authBundle: DailyTransportAuthBundle, abortController: AbortController): Promise<void>;
48
+ _validateConnectionParams(connectParams?: unknown): DailyCallOptions | undefined;
49
+ _connect(connectParams?: DailyCallOptions): Promise<void>;
42
50
  sendReadyMessage(): Promise<void>;
43
- disconnect(): Promise<void>;
51
+ _disconnect(): Promise<void>;
44
52
  sendMessage(message: RTVIMessage): void;
45
53
  }
46
54
 
@@ -1 +1 @@
1
- {"mappings":";;ASgCA;IACE,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;IACE,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C;AAED;IACE,uBAAuB,4BAA4B;IACnD,uBAAuB,4BAA4B;CACpD;AAoDD,2BAA4B,SAAQ,SAAS;gBAiB/B,EACV,mBAAwB,EACxB,6BAAqC,GACtC,GAAE,gCAAqC;IAoBxC,qBAAqB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IA2B9C,eAAe,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,IAAI;IAoBxC,UAAU,CACf,OAAO,EAAE,iBAAiB,EAC1B,cAAc,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,GACxC,IAAI;IA8BP,IAAI,eAAe,IAAI,SAAS,CAE/B;IAED,IAAI,KAAK,IAAI,cAAc,CAE1B;IAED,OAAO,KAAK,KAAK,QAKhB;IAEK,UAAU;IAKhB,SAAS,CAAC,KAAK,EAAE,MAAM;IAUvB,IAAI,WAAW,4CAEd;IAEK,UAAU;IAKhB,SAAS,CAAC,KAAK,EAAE,MAAM;IAUvB,IAAI,WAAW,4CAEd;IAEK,cAAc;IAKpB,aAAa,CAAC,SAAS,EAAE,MAAM;IAQ/B,IAAI,eAAe,4CAElB;IAED,SAAS,CAAC,MAAM,EAAE,OAAO;IAIzB,IAAI,YAAY,YAEf;IAED,SAAS,CAAC,MAAM,EAAE,OAAO;IAIzB,IAAI,YAAY,YAEf;IAEM,iBAAiB,CAAC,MAAM,EAAE,OAAO;IAQxC,IAAW,eAAe,IAAI,OAAO,CAEpC;IAED,MAAM;IA0CA,OAAO,CAAC,mBAAmB,EAAE,mBAAmB;IAKhD,WAAW;IAgCX,OAAO,CACX,UAAU,EAAE,wBAAwB,EACpC,eAAe,EAAE,eAAe;IAmC5B,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAsFjC,UAAU;IAYT,WAAW,CAAC,OAAO,EAAE,WAAW;CAiLxC","sources":["transports/lib/wavtools/lib/wav_packer.js","transports/lib/wavtools/lib/analysis/constants.js","transports/lib/wavtools/lib/analysis/audio_analysis.js","transports/lib/wavtools/lib/worklets/stream_processor.js","transports/lib/wavtools/lib/wav_stream_player.js","transports/lib/wavtools/lib/worklets/audio_processor.js","transports/lib/wavtools/lib/wav_recorder.js","transports/lib/wavtools/lib/mediastream_recorder.js","transports/lib/wavtools/index.js","transports/daily/src/src/transport.ts","transports/daily/src/src/index.ts","transports/daily/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,"export * from \"./transport\";\n"],"names":[],"version":3,"file":"index.d.ts.map"}
1
+ {"mappings":";;ASsCA;IACE,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,iDAAkD,SAAQ,mBAAmB;IAC3E,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC;AAED;IACE,uBAAuB,4BAA4B;IACnD,uBAAuB,4BAA4B;CACpD;AAED,kCAAkC,kBAAkB,GAClD,OAAO,CAAC;IACN,uBAAuB,EAAE,MAAM,IAAI,CAAC;IACpC,uBAAuB,EAAE,MAAM,IAAI,CAAC;CACrC,CAAC,CAAC;AAoDL,2BAA4B,SAAQ,SAAS;IAE3C,UAAkB,UAAU,EAAE,mBAAmB,CAAC;gBAkBtC,IAAI,GAAE,gCAAqC;IAuBvD,qBAAqB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IA2B9C,eAAe,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,IAAI;IAoBxC,UAAU,CACf,OAAO,EAAE,oBAAoB,EAC7B,cAAc,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,GACxC,IAAI;IA8BP,IAAI,eAAe,IAAI,SAAS,CAE/B;IAED,IAAI,KAAK,IAAI,cAAc,CAE1B;IAED,OAAO,KAAK,KAAK,QAKhB;IAED,cAAc;IAIR,UAAU;IAKhB,SAAS,CAAC,KAAK,EAAE,MAAM;IAUvB,IAAI,WAAW,4CAEd;IAEK,UAAU;IAKhB,SAAS,CAAC,KAAK,EAAE,MAAM;IAUvB,IAAI,WAAW,4CAEd;IAEK,cAAc;IAKpB,aAAa,CAAC,SAAS,EAAE,MAAM;IAa/B,IAAI,eAAe,4CAElB;IAED,SAAS,CAAC,MAAM,EAAE,OAAO;IAIzB,IAAI,YAAY,YAEf;IAED,SAAS,CAAC,MAAM,EAAE,OAAO;IAIzB,IAAI,YAAY,YAEf;IAEM,iBAAiB,CAAC,MAAM,EAAE,OAAO;IAQxC,IAAW,eAAe,IAAI,OAAO,CAEpC;IAED,MAAM;IAuCA,OAAO,CAAC,gBAAgB,EAAE,gBAAgB;IAK1C,WAAW;IAgCjB,yBAAyB,CACvB,aAAa,CAAC,EAAE,OAAO,GACtB,gBAAgB,GAAG,SAAS;IAsBzB,QAAQ,CAAC,aAAa,CAAC,EAAE,gBAAgB;IA6BzC,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IA8FjC,WAAW;IAYV,WAAW,CAAC,OAAO,EAAE,WAAW;CA8OxC","sources":["transports/lib/wavtools/lib/wav_packer.js","transports/lib/wavtools/lib/analysis/constants.js","transports/lib/wavtools/lib/analysis/audio_analysis.js","transports/lib/wavtools/lib/worklets/stream_processor.js","transports/lib/wavtools/lib/wav_stream_player.js","transports/lib/wavtools/lib/worklets/audio_processor.js","transports/lib/wavtools/lib/wav_recorder.js","transports/lib/wavtools/lib/mediastream_recorder.js","transports/lib/wavtools/index.js","transports/daily/src/src/transport.ts","transports/daily/src/src/index.ts","transports/daily/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,"export * from \"./transport\";\n"],"names":[],"version":3,"file":"index.d.ts.map"}
package/dist/index.js CHANGED
@@ -801,6 +801,7 @@ class $0d471c38435bdab6$export$439b217ca659a877 {
801
801
  this.outputToSpeakers = outputToSpeakers;
802
802
  this.debug = !!debug;
803
803
  this._deviceChangeCallback = null;
804
+ this._deviceErrorCallback = null;
804
805
  this._devices = [];
805
806
  this.deviceSelection = null;
806
807
  // State variables
@@ -959,21 +960,42 @@ class $0d471c38435bdab6$export$439b217ca659a877 {
959
960
  return true;
960
961
  }
961
962
  /**
963
+ * Provide a callback for if/when device errors occur
964
+ * @param {(({devices: Array<"cam" | "mic">, type: string, error?: Error}) => void) | null} callback
965
+ * @returns {true}
966
+ */ listenForDeviceErrors(callback) {
967
+ this._deviceErrorCallback = callback;
968
+ }
969
+ /**
962
970
  * Manually request permission to use the microphone
963
971
  * @returns {Promise<true>}
964
972
  */ async requestPermission() {
965
973
  const permissionStatus = await navigator.permissions.query({
966
974
  name: 'microphone'
967
975
  });
968
- if (permissionStatus.state === 'denied') window.alert('You must grant microphone access to use this feature.');
969
- else if (permissionStatus.state === 'prompt') try {
976
+ if (permissionStatus.state === 'denied') {
977
+ if (this._deviceErrorCallback) this._deviceErrorCallback({
978
+ devices: [
979
+ "mic"
980
+ ],
981
+ type: "unknown",
982
+ error: new Error("Microphone access denied")
983
+ });
984
+ } else if (permissionStatus.state === 'prompt') try {
970
985
  const stream = await navigator.mediaDevices.getUserMedia({
971
986
  audio: true
972
987
  });
973
988
  const tracks = stream.getTracks();
974
989
  tracks.forEach((track)=>track.stop());
975
990
  } catch (e) {
976
- window.alert('You must grant microphone access to use this feature.');
991
+ console.error("Error accessing microphone.");
992
+ if (this._deviceErrorCallback) this._deviceErrorCallback({
993
+ devices: [
994
+ "mic"
995
+ ],
996
+ type: "unknown",
997
+ error: e
998
+ });
977
999
  }
978
1000
  return true;
979
1001
  }
@@ -1010,7 +1032,16 @@ class $0d471c38435bdab6$export$439b217ca659a877 {
1010
1032
  * @returns {Promise<true>}
1011
1033
  */ async begin(deviceId) {
1012
1034
  if (this.processor) throw new Error(`Already connected: please call .end() to start a new session`);
1013
- if (!navigator.mediaDevices || !('getUserMedia' in navigator.mediaDevices)) throw new Error('Could not request user media');
1035
+ if (!navigator.mediaDevices || !('getUserMedia' in navigator.mediaDevices)) {
1036
+ if (this._deviceErrorCallback) this._deviceErrorCallback({
1037
+ devices: [
1038
+ "mic",
1039
+ "cam"
1040
+ ],
1041
+ type: "undefined-mediadevices"
1042
+ });
1043
+ throw new Error('Could not request user media');
1044
+ }
1014
1045
  deviceId = deviceId ?? this.deviceSelection?.deviceId;
1015
1046
  try {
1016
1047
  const config = {
@@ -1023,6 +1054,13 @@ class $0d471c38435bdab6$export$439b217ca659a877 {
1023
1054
  };
1024
1055
  this.stream = await navigator.mediaDevices.getUserMedia(config);
1025
1056
  } catch (err) {
1057
+ if (this._deviceErrorCallback) this._deviceErrorCallback({
1058
+ devices: [
1059
+ "mic"
1060
+ ],
1061
+ type: "unknown",
1062
+ error: err
1063
+ });
1026
1064
  throw new Error('Could not start media stream');
1027
1065
  }
1028
1066
  this.listDevices().then((devices)=>{
@@ -1444,7 +1482,7 @@ globalThis.WavRecorder = WavRecorder;
1444
1482
 
1445
1483
 
1446
1484
  var $c2e964a535c1120e$exports = {};
1447
- $c2e964a535c1120e$exports = JSON.parse("{\"name\":\"@pipecat-ai/daily-transport\",\"version\":\"0.4.0\",\"license\":\"BSD-2-Clause\",\"main\":\"dist/index.js\",\"module\":\"dist/index.module.js\",\"types\":\"dist/index.d.ts\",\"source\":\"src/index.ts\",\"repository\":{\"type\":\"git\",\"url\":\"git+https://github.com/pipecat-ai/pipecat-client-web-transports.git\"},\"files\":[\"dist\",\"package.json\",\"README.md\"],\"scripts\":{\"build\":\"parcel build --no-cache\",\"dev\":\"parcel watch\",\"lint\":\"eslint . --ext ts --report-unused-disable-directives --max-warnings 0\"},\"devDependencies\":{\"@pipecat-ai/client-js\":\"^0.4.0\",\"eslint\":\"9.11.1\",\"eslint-config-prettier\":\"^9.1.0\",\"eslint-plugin-simple-import-sort\":\"^12.1.1\"},\"peerDependencies\":{\"@pipecat-ai/client-js\":\"~0.4.0\"},\"dependencies\":{\"@daily-co/daily-js\":\"^0.77.0\"},\"description\":\"Pipecat Daily Transport Package\",\"author\":\"Daily.co\",\"bugs\":{\"url\":\"https://github.com/pipecat-ai/pipecat-client-web-transports/issues\"},\"homepage\":\"https://github.com/pipecat-ai/pipecat-client-web-transports/blob/main/transports/daily-webrtc/README.md\"}");
1485
+ $c2e964a535c1120e$exports = JSON.parse("{\"name\":\"@pipecat-ai/daily-transport\",\"version\":\"1.1.0\",\"license\":\"BSD-2-Clause\",\"main\":\"dist/index.js\",\"module\":\"dist/index.module.js\",\"types\":\"dist/index.d.ts\",\"source\":\"src/index.ts\",\"repository\":{\"type\":\"git\",\"url\":\"git+https://github.com/pipecat-ai/pipecat-client-web-transports.git\"},\"files\":[\"dist\",\"package.json\",\"README.md\"],\"scripts\":{\"build\":\"parcel build --no-cache\",\"dev\":\"parcel watch\",\"lint\":\"eslint . --ext ts --report-unused-disable-directives --max-warnings 0\"},\"devDependencies\":{\"@pipecat-ai/client-js\":\"^1.1.0\",\"eslint\":\"9.11.1\",\"eslint-config-prettier\":\"^9.1.0\",\"eslint-plugin-simple-import-sort\":\"^12.1.1\"},\"peerDependencies\":{\"@pipecat-ai/client-js\":\"~1.1.0\"},\"dependencies\":{\"@daily-co/daily-js\":\"^0.77.0\"},\"description\":\"Pipecat Daily Transport Package\",\"author\":\"Daily.co\",\"bugs\":{\"url\":\"https://github.com/pipecat-ai/pipecat-client-web-transports/issues\"},\"homepage\":\"https://github.com/pipecat-ai/pipecat-client-web-transports/blob/main/transports/daily-webrtc/README.md\"}");
1448
1486
 
1449
1487
 
1450
1488
  var $28bdeb35415d61e8$export$ef180de88fd317cc;
@@ -1461,18 +1499,18 @@ class $28bdeb35415d61e8$var$DailyCallWrapper {
1461
1499
  let errMsg;
1462
1500
  switch(String(prop)){
1463
1501
  // Disable methods that modify the lifecycle of the call. These operations
1464
- // should be performed via the RTVI client in order to keep state in sync.
1502
+ // should be performed via the PipecatClient in order to keep state in sync.
1465
1503
  case "preAuth":
1466
1504
  errMsg = `Calls to preAuth() are disabled. Please use Transport.preAuth()`;
1467
1505
  break;
1468
1506
  case "startCamera":
1469
- errMsg = `Calls to startCamera() are disabled. Please use RTVIClient.initDevices()`;
1507
+ errMsg = `Calls to startCamera() are disabled. Please use PipecatClient.initDevices()`;
1470
1508
  break;
1471
1509
  case "join":
1472
- errMsg = `Calls to join() are disabled. Please use RTVIClient.connect()`;
1510
+ errMsg = `Calls to join() are disabled. Please use PipecatClient.connect()`;
1473
1511
  break;
1474
1512
  case "leave":
1475
- errMsg = `Calls to leave() are disabled. Please use RTVIClient.disconnect()`;
1513
+ errMsg = `Calls to leave() are disabled. Please use PipecatClient.disconnect()`;
1476
1514
  break;
1477
1515
  case "destroy":
1478
1516
  errMsg = `Calls to destroy() are disabled.`;
@@ -1496,7 +1534,7 @@ class $28bdeb35415d61e8$var$DailyCallWrapper {
1496
1534
  }
1497
1535
  }
1498
1536
  class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclientjs.Transport) {
1499
- constructor({ dailyFactoryOptions: dailyFactoryOptions = {}, bufferLocalAudioUntilBotReady: bufferLocalAudioUntilBotReady = false } = {}){
1537
+ constructor(opts = {}){
1500
1538
  super();
1501
1539
  this._botId = "";
1502
1540
  this._selectedCam = {};
@@ -1505,8 +1543,9 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
1505
1543
  this._currentAudioTrack = null;
1506
1544
  this._audioQueue = [];
1507
1545
  this._callbacks = {};
1508
- this._dailyFactoryOptions = dailyFactoryOptions;
1509
- this._bufferLocalAudioUntilBotReady = bufferLocalAudioUntilBotReady;
1546
+ const { bufferLocalAudioUntilBotReady: bufferLocalAudioUntilBotReady, ...dailyOpts } = opts;
1547
+ this._dailyFactoryOptions = dailyOpts;
1548
+ this._bufferLocalAudioUntilBotReady = bufferLocalAudioUntilBotReady || false;
1510
1549
  this._daily = (0, ($parcel$interopDefault($jrPAn$dailycodailyjs))).createCallObject({
1511
1550
  ...this._dailyFactoryOptions,
1512
1551
  allowMultipleCallInstances: true
@@ -1540,7 +1579,7 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
1540
1579
  const pcmByteArray = new Uint8Array(data);
1541
1580
  return btoa(String.fromCharCode(...pcmByteArray));
1542
1581
  });
1543
- const rtviMessage = {
1582
+ const audioMessage = {
1544
1583
  id: "raw-audio-batch",
1545
1584
  label: "rtvi-ai",
1546
1585
  type: "raw-audio-batch",
@@ -1550,7 +1589,7 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
1550
1589
  numChannels: 1
1551
1590
  }
1552
1591
  };
1553
- this.sendMessage(rtviMessage);
1592
+ this.sendMessage(audioMessage);
1554
1593
  }
1555
1594
  initialize(options, messageHandler) {
1556
1595
  if (this._bufferLocalAudioUntilBotReady) this.setupRecorder();
@@ -1562,7 +1601,7 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
1562
1601
  this._dailyFactoryOptions.startAudioOff = !(options.enableMic ?? true);
1563
1602
  this.attachEventListeners();
1564
1603
  this.state = "disconnected";
1565
- (0, $jrPAn$pipecataiclientjs.logger).debug("[RTVI Transport] Initialized", (0, (/*@__PURE__*/$parcel$interopDefault($c2e964a535c1120e$exports))).version);
1604
+ (0, $jrPAn$pipecataiclientjs.logger).debug("[Daily Transport] Initialized", (0, (/*@__PURE__*/$parcel$interopDefault($c2e964a535c1120e$exports))).version);
1566
1605
  }
1567
1606
  get dailyCallClient() {
1568
1607
  return this._dailyWrapper.proxy;
@@ -1575,6 +1614,9 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
1575
1614
  this._state = state;
1576
1615
  this._callbacks.onTransportStateChanged?.(state);
1577
1616
  }
1617
+ getSessionInfo() {
1618
+ return this._daily.meetingSessionSummary();
1619
+ }
1578
1620
  async getAllCams() {
1579
1621
  const { devices: devices } = await this._daily.enumerateDevices();
1580
1622
  return devices.filter((d)=>d.kind === "videoinput");
@@ -1612,6 +1654,10 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
1612
1654
  outputDeviceId: speakerId
1613
1655
  }).then((infos)=>{
1614
1656
  this._selectedSpeaker = infos.speaker;
1657
+ }).catch((e)=>{
1658
+ this._callbacks.onDeviceError?.(new (0, $jrPAn$pipecataiclientjs.DeviceError)([
1659
+ "speaker"
1660
+ ], e.type ?? "unknown", e.message));
1615
1661
  });
1616
1662
  }
1617
1663
  get selectedSpeaker() {
@@ -1655,23 +1701,20 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
1655
1701
  }
1656
1702
  async startRecording() {
1657
1703
  try {
1658
- (0, $jrPAn$pipecataiclientjs.logger).info("[RTVI Transport] Initializing recording");
1704
+ (0, $jrPAn$pipecataiclientjs.logger).info("[Daily Transport] Initializing recording");
1659
1705
  await this._mediaStreamRecorder.record((data)=>{
1660
1706
  this.handleUserAudioStream(data.mono);
1661
1707
  }, $28bdeb35415d61e8$export$b1ca982aa1e488c1.RECORDER_CHUNK_SIZE);
1662
- this._onMessage({
1663
- type: $28bdeb35415d61e8$export$ef180de88fd317cc.AUDIO_BUFFERING_STARTED,
1664
- data: {}
1665
- });
1666
- (0, $jrPAn$pipecataiclientjs.logger).info("[RTVI Transport] Recording Initialized");
1708
+ this._callbacks.onAudioBufferingStarted?.();
1709
+ (0, $jrPAn$pipecataiclientjs.logger).info("[Daily Transport] Recording Initialized");
1667
1710
  } catch (e) {
1668
1711
  const err = e;
1669
1712
  if (!err.message.includes("Already recording")) (0, $jrPAn$pipecataiclientjs.logger).error("Error starting recording", e);
1670
1713
  }
1671
1714
  }
1672
- async preAuth(dailyFactoryOptions) {
1673
- this._dailyFactoryOptions = dailyFactoryOptions;
1674
- await this._daily.preAuth(dailyFactoryOptions);
1715
+ async preAuth(dailyCallOptions) {
1716
+ this._dailyFactoryOptions = dailyCallOptions;
1717
+ await this._daily.preAuth(dailyCallOptions);
1675
1718
  }
1676
1719
  async initDevices() {
1677
1720
  if (!this._daily) throw new (0, $jrPAn$pipecataiclientjs.RTVIError)("Transport instance not initialized");
@@ -1695,23 +1738,33 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
1695
1738
  if (!this._daily.isRemoteParticipantsAudioLevelObserverRunning()) await this._daily.startRemoteParticipantsAudioLevelObserver(100);
1696
1739
  this.state = "initialized";
1697
1740
  }
1698
- async connect(authBundle, abortController) {
1741
+ _validateConnectionParams(connectParams) {
1742
+ if (connectParams === undefined || connectParams === null) return undefined;
1743
+ if (typeof connectParams !== "object") throw new (0, $jrPAn$pipecataiclientjs.RTVIError)("Invalid connection parameters");
1744
+ const tmpParams = connectParams;
1745
+ if (tmpParams.room_url) {
1746
+ tmpParams.url = tmpParams.room_url;
1747
+ delete tmpParams.room_url;
1748
+ }
1749
+ if (!tmpParams.token) // Daily doesn't like token being in the map and undefined or null
1750
+ delete tmpParams.token;
1751
+ return tmpParams;
1752
+ }
1753
+ async _connect(connectParams) {
1699
1754
  if (!this._daily) throw new (0, $jrPAn$pipecataiclientjs.RTVIError)("Transport instance not initialized");
1700
- if (abortController.signal.aborted) return;
1755
+ if (connectParams) this._dailyFactoryOptions = {
1756
+ ...this._dailyFactoryOptions,
1757
+ ...connectParams
1758
+ };
1701
1759
  this.state = "connecting";
1702
- const opts = this._dailyFactoryOptions;
1703
- opts.url = authBundle.room_url ?? opts.url;
1704
- if (authBundle.token != null) opts.token = authBundle.token;
1705
1760
  try {
1706
- await this._daily.join(opts);
1707
- const room = await this._daily.room();
1708
- if (room && "id" in room) this._expiry = room.config?.exp;
1761
+ await this._daily.join(this._dailyFactoryOptions);
1709
1762
  } catch (e) {
1710
1763
  (0, $jrPAn$pipecataiclientjs.logger).error("Failed to join room", e);
1711
1764
  this.state = "error";
1712
1765
  throw new (0, $jrPAn$pipecataiclientjs.TransportStartError)();
1713
1766
  }
1714
- if (abortController.signal.aborted) return;
1767
+ if (this._abortController?.signal.aborted) return;
1715
1768
  this.state = "connected";
1716
1769
  this._callbacks.onConnected?.();
1717
1770
  }
@@ -1729,12 +1782,21 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
1729
1782
  this.stopRecording();
1730
1783
  resolve();
1731
1784
  };
1785
+ for(const id in this._daily.participants()){
1786
+ const p = this._daily.participants()[id];
1787
+ if (!p.local && p.tracks?.audio?.persistentTrack) {
1788
+ // If we already have a remote audio track, we can send the ready message immediately
1789
+ sendReadyMessage();
1790
+ resolve();
1791
+ return;
1792
+ }
1793
+ }
1732
1794
  const readyHandler = (ev)=>{
1733
1795
  if (!ev.participant?.local) {
1734
1796
  this._daily.off("track-started", readyHandler);
1735
1797
  // Check if it's an iOS device
1736
1798
  if (isIOS()) {
1737
- (0, $jrPAn$pipecataiclientjs.logger).debug("[RTVI Transport] iOS device detected, adding 0.5 second delay before sending ready message");
1799
+ (0, $jrPAn$pipecataiclientjs.logger).debug("[Daily Transport] iOS device detected, adding 0.5 second delay before sending ready message");
1738
1800
  // Add 500ms delay for iOS devices:
1739
1801
  // This is a workaround for iOS devices clipping a portion
1740
1802
  // of the audio after the track becomes playable.
@@ -1750,15 +1812,13 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
1750
1812
  if (this._mediaStreamRecorder && this._mediaStreamRecorder.getStatus() !== "ended") {
1751
1813
  // disconnecting, we don't need to record anymore
1752
1814
  this._mediaStreamRecorder.end();
1753
- this._onMessage({
1754
- type: $28bdeb35415d61e8$export$ef180de88fd317cc.AUDIO_BUFFERING_STOPPED,
1755
- data: {}
1756
- });
1815
+ this._callbacks.onAudioBufferingStopped?.();
1757
1816
  }
1758
1817
  }
1759
1818
  attachEventListeners() {
1760
1819
  this._daily.on("available-devices-updated", this.handleAvailableDevicesUpdated.bind(this));
1761
1820
  this._daily.on("selected-devices-updated", this.handleSelectedDevicesUpdated.bind(this));
1821
+ this._daily.on("camera-error", this.handleDeviceError.bind(this));
1762
1822
  this._daily.on("track-started", this.handleTrackStarted.bind(this));
1763
1823
  this._daily.on("track-stopped", this.handleTrackStopped.bind(this));
1764
1824
  this._daily.on("participant-joined", this.handleParticipantJoined.bind(this));
@@ -1770,7 +1830,7 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
1770
1830
  this._daily.on("error", this.handleFatalError.bind(this));
1771
1831
  this._daily.on("nonfatal-error", this.handleNonFatalError.bind(this));
1772
1832
  }
1773
- async disconnect() {
1833
+ async _disconnect() {
1774
1834
  this.state = "disconnecting";
1775
1835
  this._daily.stopLocalAudioLevelObserver();
1776
1836
  this._daily.stopRemoteParticipantsAudioLevelObserver();
@@ -1809,24 +1869,74 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
1809
1869
  this._callbacks.onSpeakerUpdated?.(ev.devices.speaker);
1810
1870
  }
1811
1871
  }
1872
+ handleDeviceError(ev) {
1873
+ const generateDeviceError = (error)=>{
1874
+ const devices = [];
1875
+ switch(error.type){
1876
+ case "permissions":
1877
+ error.blockedMedia.forEach((d)=>{
1878
+ devices.push(d === "video" ? "cam" : "mic");
1879
+ });
1880
+ return new (0, $jrPAn$pipecataiclientjs.DeviceError)(devices, error.type, error.msg, {
1881
+ blockedBy: error.blockedBy
1882
+ });
1883
+ case "not-found":
1884
+ error.missingMedia.forEach((d)=>{
1885
+ devices.push(d === "video" ? "cam" : "mic");
1886
+ });
1887
+ return new (0, $jrPAn$pipecataiclientjs.DeviceError)(devices, error.type, error.msg);
1888
+ case "constraints":
1889
+ error.failedMedia.forEach((d)=>{
1890
+ devices.push(d === "video" ? "cam" : "mic");
1891
+ });
1892
+ return new (0, $jrPAn$pipecataiclientjs.DeviceError)(devices, error.type, error.msg, {
1893
+ reason: error.reason
1894
+ });
1895
+ case "cam-in-use":
1896
+ devices.push("cam");
1897
+ return new (0, $jrPAn$pipecataiclientjs.DeviceError)(devices, "in-use", error.msg);
1898
+ case "mic-in-use":
1899
+ devices.push("mic");
1900
+ return new (0, $jrPAn$pipecataiclientjs.DeviceError)(devices, "in-use", error.msg);
1901
+ case "cam-mic-in-use":
1902
+ devices.push("cam");
1903
+ devices.push("mic");
1904
+ return new (0, $jrPAn$pipecataiclientjs.DeviceError)(devices, "in-use", error.msg);
1905
+ case "undefined-mediadevices":
1906
+ case "unknown":
1907
+ default:
1908
+ devices.push("cam");
1909
+ devices.push("mic");
1910
+ return new (0, $jrPAn$pipecataiclientjs.DeviceError)(devices, error.type, error.msg);
1911
+ }
1912
+ };
1913
+ this._callbacks.onDeviceError?.(generateDeviceError(ev.error));
1914
+ }
1812
1915
  async handleLocalAudioTrack(track) {
1813
1916
  if (this.state == "ready" || !this._bufferLocalAudioUntilBotReady) return;
1814
1917
  const status = this._mediaStreamRecorder.getStatus();
1815
1918
  switch(status){
1816
1919
  case "ended":
1817
- await this._mediaStreamRecorder.begin(track);
1818
- await this.startRecording();
1920
+ try {
1921
+ await this._mediaStreamRecorder.begin(track);
1922
+ await this.startRecording();
1923
+ } catch (e) {
1924
+ // void. nothing to do.
1925
+ }
1819
1926
  break;
1820
1927
  case "paused":
1821
1928
  await this.startRecording();
1822
1929
  break;
1823
1930
  case "recording":
1824
1931
  default:
1825
- if (this._currentAudioTrack !== track) {
1932
+ if (this._currentAudioTrack !== track) try {
1826
1933
  await this._mediaStreamRecorder.end();
1827
1934
  await this._mediaStreamRecorder.begin(track);
1828
1935
  await this.startRecording();
1829
- } else (0, $jrPAn$pipecataiclientjs.logger).warn("track-started event received for current track and already recording");
1936
+ } catch (e) {
1937
+ // void. nothing to do.
1938
+ }
1939
+ else (0, $jrPAn$pipecataiclientjs.logger).warn("track-started event received for current track and already recording");
1830
1940
  break;
1831
1941
  }
1832
1942
  this._currentAudioTrack = track;