@estuary-ai/sdk 0.1.28 → 0.1.30

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
@@ -9167,24 +9167,24 @@ async function isLiveKitAvailable() {
9167
9167
  async function createVoiceManager(transport, socketManager, sampleRate, logger) {
9168
9168
  if (transport === "websocket") {
9169
9169
  const { WebSocketVoiceManager: WebSocketVoiceManager2 } = await Promise.resolve().then(() => (init_websocket_voice(), websocket_voice_exports));
9170
- return new WebSocketVoiceManager2(socketManager, sampleRate, logger);
9170
+ return { manager: new WebSocketVoiceManager2(socketManager, sampleRate, logger), resolvedTransport: "websocket" };
9171
9171
  }
9172
9172
  if (transport === "livekit") {
9173
9173
  if (await isLiveKitAvailable()) {
9174
9174
  const { LiveKitVoiceManager: LiveKitVoiceManager2 } = await Promise.resolve().then(() => (init_livekit_voice(), livekit_voice_exports));
9175
- return new LiveKitVoiceManager2(socketManager, logger);
9175
+ return { manager: new LiveKitVoiceManager2(socketManager, logger), resolvedTransport: "livekit" };
9176
9176
  }
9177
9177
  logger.warn("livekit-client not installed, falling back to WebSocket voice");
9178
9178
  const { WebSocketVoiceManager: WebSocketVoiceManager2 } = await Promise.resolve().then(() => (init_websocket_voice(), websocket_voice_exports));
9179
- return new WebSocketVoiceManager2(socketManager, sampleRate, logger);
9179
+ return { manager: new WebSocketVoiceManager2(socketManager, sampleRate, logger), resolvedTransport: "websocket" };
9180
9180
  }
9181
9181
  if (transport === "auto") {
9182
9182
  if (await isLiveKitAvailable()) {
9183
9183
  const { LiveKitVoiceManager: LiveKitVoiceManager2 } = await Promise.resolve().then(() => (init_livekit_voice(), livekit_voice_exports));
9184
- return new LiveKitVoiceManager2(socketManager, logger);
9184
+ return { manager: new LiveKitVoiceManager2(socketManager, logger), resolvedTransport: "livekit" };
9185
9185
  }
9186
9186
  const { WebSocketVoiceManager: WebSocketVoiceManager2 } = await Promise.resolve().then(() => (init_websocket_voice(), websocket_voice_exports));
9187
- return new WebSocketVoiceManager2(socketManager, sampleRate, logger);
9187
+ return { manager: new WebSocketVoiceManager2(socketManager, sampleRate, logger), resolvedTransport: "websocket" };
9188
9188
  }
9189
9189
  return null;
9190
9190
  }
@@ -9319,7 +9319,7 @@ var CharacterClient = class {
9319
9319
  };
9320
9320
 
9321
9321
  // src/audio/audio-player.ts
9322
- var AudioPlayer = class {
9322
+ var AudioPlayer = class _AudioPlayer {
9323
9323
  sampleRate;
9324
9324
  onEvent;
9325
9325
  audioContext = null;
@@ -9331,6 +9331,8 @@ var AudioPlayer = class {
9331
9331
  isPlaying = false;
9332
9332
  _isCleared = false;
9333
9333
  _interruptedMessageId = null;
9334
+ _drainTimer = null;
9335
+ static DRAIN_DELAY_MS = 300;
9334
9336
  constructor(sampleRate, onEvent) {
9335
9337
  this.sampleRate = sampleRate;
9336
9338
  this.onEvent = onEvent;
@@ -9353,6 +9355,7 @@ var AudioPlayer = class {
9353
9355
  this._interruptedMessageId = null;
9354
9356
  }
9355
9357
  this._isCleared = false;
9358
+ this.cancelDrain();
9356
9359
  const ctx = this.getAudioContext();
9357
9360
  if (!ctx) return;
9358
9361
  const pcm16 = base64ToInt16Array(voice.audio);
@@ -9366,6 +9369,7 @@ var AudioPlayer = class {
9366
9369
  }
9367
9370
  clear() {
9368
9371
  this._isCleared = true;
9372
+ this.cancelDrain();
9369
9373
  this.queue.length = 0;
9370
9374
  if (this.currentSource) {
9371
9375
  try {
@@ -9391,6 +9395,7 @@ var AudioPlayer = class {
9391
9395
  this.currentMessageId = null;
9392
9396
  }
9393
9397
  dispose() {
9398
+ this.cancelDrain();
9394
9399
  this.clear();
9395
9400
  if (this.audioElement) {
9396
9401
  this.audioElement.pause();
@@ -9408,6 +9413,25 @@ var AudioPlayer = class {
9408
9413
  this.audioContext = null;
9409
9414
  }
9410
9415
  }
9416
+ /** Schedule a deferred 'complete' event. Cancelled if new chunks arrive. */
9417
+ scheduleDrain() {
9418
+ if (this._drainTimer !== null) return;
9419
+ this._drainTimer = setTimeout(() => {
9420
+ this._drainTimer = null;
9421
+ if (this._isCleared) return;
9422
+ if (this.queue.length === 0 && this.isPlaying && this.currentMessageId) {
9423
+ this.onEvent({ type: "complete", messageId: this.currentMessageId });
9424
+ this.isPlaying = false;
9425
+ this.currentMessageId = null;
9426
+ }
9427
+ }, _AudioPlayer.DRAIN_DELAY_MS);
9428
+ }
9429
+ cancelDrain() {
9430
+ if (this._drainTimer !== null) {
9431
+ clearTimeout(this._drainTimer);
9432
+ this._drainTimer = null;
9433
+ }
9434
+ }
9411
9435
  getAudioContext() {
9412
9436
  if (this.audioContext) return this.audioContext;
9413
9437
  if (typeof AudioContext === "undefined" && typeof globalThis.webkitAudioContext === "undefined") {
@@ -9434,10 +9458,8 @@ var AudioPlayer = class {
9434
9458
  const ctx = this.getAudioContext();
9435
9459
  if (!ctx || this.queue.length === 0) {
9436
9460
  if (this.isPlaying && this.currentMessageId) {
9437
- this.onEvent({ type: "complete", messageId: this.currentMessageId });
9461
+ this.scheduleDrain();
9438
9462
  }
9439
- this.isPlaying = false;
9440
- this.currentMessageId = null;
9441
9463
  return;
9442
9464
  }
9443
9465
  const { buffer, messageId } = this.queue.shift();
@@ -9672,11 +9694,12 @@ var EstuaryClient = class extends TypedEventEmitter {
9672
9694
  }
9673
9695
  const transport = this.config.voiceTransport ?? "auto";
9674
9696
  const sampleRate = this.config.audioSampleRate ?? DEFAULT_SAMPLE_RATE;
9675
- this.voiceManager = await createVoiceManager(transport, this.socketManager, sampleRate, this.logger);
9676
- if (!this.voiceManager) {
9697
+ const result = await createVoiceManager(transport, this.socketManager, sampleRate, this.logger);
9698
+ if (!result) {
9677
9699
  throw new exports.EstuaryError("VOICE_NOT_SUPPORTED" /* VOICE_NOT_SUPPORTED */, "No voice transport available");
9678
9700
  }
9679
- if (!this.audioPlayer && typeof AudioContext !== "undefined") {
9701
+ this.voiceManager = result.manager;
9702
+ if (!this.audioPlayer && result.resolvedTransport === "websocket" && typeof AudioContext !== "undefined") {
9680
9703
  this.audioPlayer = new AudioPlayer(sampleRate, (event) => {
9681
9704
  if (event.type === "started") {
9682
9705
  this._hasAutoInterrupted = true;