@superinterface/react 5.3.0-beta.4 → 5.3.0-beta.5

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.cjs CHANGED
@@ -47436,39 +47436,57 @@ function _toPrimitive47(t, r) {
47436
47436
  }
47437
47437
  return ("string" === r ? String : Number)(t);
47438
47438
  }
47439
+ var THROTTLE_MS = 80;
47440
+ var MAX_SEG_CACHE = 256;
47441
+ var KEEP_FINISHED_MESSAGES = 12;
47442
+ var hasLetters = function(s) {
47443
+ for(var i = 0; i < s.length; i++){
47444
+ var ch = s.charAt(i);
47445
+ if (ch.toLowerCase() !== ch.toUpperCase()) return true;
47446
+ }
47447
+ return false;
47448
+ };
47439
47449
  var splitSentencesFast = function(text) {
47440
47450
  var t = text.replace(/\s+/g, " ").trim();
47441
47451
  if (!t) return [];
47442
47452
  var parts = t.split(RegExp("(?<=[.!?])\\s+(?=[^\\s])", "g"));
47443
- return parts;
47444
- };
47445
- var getIncrementalSentences = function(prev, nextInput) {
47446
- if (!prev) {
47447
- return {
47448
- input: nextInput,
47449
- sentences: splitSentencesFast(nextInput)
47450
- };
47451
- }
47452
- if (nextInput === prev.input) {
47453
- return prev;
47453
+ var filtered = [];
47454
+ for(var i = 0; i < parts.length; i++){
47455
+ var p = parts[i].trim();
47456
+ if (p && hasLetters(p)) filtered.push(p);
47454
47457
  }
47458
+ return filtered;
47459
+ };
47460
+ var getIncrementalSentences = function(prev, nextInput, now) {
47461
+ if (!prev) return {
47462
+ input: nextInput,
47463
+ sentences: splitSentencesFast(nextInput),
47464
+ touched: now
47465
+ };
47466
+ if (nextInput === prev.input) return {
47467
+ input: prev.input,
47468
+ sentences: prev.sentences,
47469
+ touched: now
47470
+ };
47455
47471
  if (nextInput.startsWith(prev.input)) {
47456
- var _prev$sentences;
47457
- var prevLast = (_prev$sentences = prev.sentences[prev.sentences.length - 1]) !== null && _prev$sentences !== void 0 ? _prev$sentences : "";
47472
+ var prevSentences = prev.sentences;
47473
+ var prevLast = prevSentences[prevSentences.length - 1] || "";
47458
47474
  var baseLen = prev.input.length - prevLast.length;
47459
47475
  if (baseLen >= 0 && prev.input.slice(baseLen) === prevLast) {
47460
47476
  var tail = nextInput.slice(baseLen);
47461
47477
  var tailSegments = splitSentencesFast(tail);
47462
- var merged = prev.sentences.length > 0 ? _to_consumable_array(prev.sentences.slice(0, -1)).concat(_to_consumable_array(tailSegments)) : tailSegments;
47478
+ var merged = prevSentences.length > 0 ? prevSentences.slice(0, -1).concat(tailSegments) : tailSegments;
47463
47479
  return {
47464
47480
  input: nextInput,
47465
- sentences: merged
47481
+ sentences: merged,
47482
+ touched: now
47466
47483
  };
47467
47484
  }
47468
47485
  }
47469
47486
  return {
47470
47487
  input: nextInput,
47471
- sentences: splitSentencesFast(nextInput)
47488
+ sentences: splitSentencesFast(nextInput),
47489
+ touched: now
47472
47490
  };
47473
47491
  };
47474
47492
  var useMessageAudio = function(_ref) {
@@ -47489,41 +47507,65 @@ var useMessageAudio = function(_ref) {
47489
47507
  var currentSentenceRef = (0, import_react67.useRef)(null);
47490
47508
  var messagesProps = useMessages();
47491
47509
  var segCacheRef = (0, import_react67.useRef)(/* @__PURE__ */ new Map());
47510
+ var mirrorTimerRef = (0, import_react67.useRef)(null);
47511
+ var pendingMirrorRef = (0, import_react67.useRef)(false);
47492
47512
  (0, import_react67.useEffect)(function() {
47493
- var assistantsDesc = messagesProps.messages.filter(function(m) {
47494
- return m.role === "assistant";
47495
- });
47496
- var assistantsAsc = _to_consumable_array(assistantsDesc).reverse();
47497
- setAudioQueue(function(prev) {
47498
- var prevById = new Map(prev.map(function(p) {
47499
- return [
47500
- p.id,
47501
- p
47502
- ];
47503
- }));
47504
- var changed = false;
47505
- var next = [];
47506
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
47507
- try {
47508
- for(var _iterator = assistantsAsc[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
47509
- var m_0 = _step.value;
47513
+ if (mirrorTimerRef.current != null) {
47514
+ pendingMirrorRef.current = true;
47515
+ return;
47516
+ }
47517
+ var run = function() {
47518
+ var assistantsDesc = messagesProps.messages.filter(function(m) {
47519
+ return m.role === "assistant";
47520
+ });
47521
+ var assistantsAsc = assistantsDesc.slice().reverse();
47522
+ var nowTs = typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
47523
+ var segCache = segCacheRef.current;
47524
+ var touch = function(id, entry) {
47525
+ segCache.set(id, {
47526
+ input: entry.input,
47527
+ sentences: entry.sentences,
47528
+ touched: nowTs
47529
+ });
47530
+ };
47531
+ var evictLRU = function() {
47532
+ if (segCache.size <= MAX_SEG_CACHE) return;
47533
+ var entries = Array.from(segCache.entries());
47534
+ entries.sort(function(a, b) {
47535
+ return a[1].touched - b[1].touched;
47536
+ });
47537
+ var toRemove = segCache.size - MAX_SEG_CACHE;
47538
+ for(var i = 0; i < toRemove; i++)segCache.delete(entries[i][0]);
47539
+ };
47540
+ setAudioQueue(function(prev) {
47541
+ var prevById = new Map(prev.map(function(p) {
47542
+ return [
47543
+ p.id,
47544
+ p
47545
+ ];
47546
+ }));
47547
+ var next = [];
47548
+ var changed = false;
47549
+ for(var i_0 = 0; i_0 < assistantsAsc.length; i_0++){
47510
47550
  var _existing$nextIndex, _existing$stopped;
47551
+ var m_0 = assistantsAsc[i_0];
47511
47552
  var inp = input({
47512
47553
  message: m_0
47513
47554
  });
47514
47555
  if (inp == null) continue;
47515
- var prevSeg = segCacheRef.current.get(m_0.id);
47516
- var nextSeg = getIncrementalSentences(prevSeg, inp);
47517
- if (!prevSeg || nextSeg.input !== prevSeg.input) {
47518
- segCacheRef.current.set(m_0.id, nextSeg);
47556
+ var prevSeg = segCache.get(m_0.id);
47557
+ var nextSeg = getIncrementalSentences(prevSeg, inp, nowTs);
47558
+ if (!prevSeg || nextSeg.input !== prevSeg.input || nextSeg.sentences !== prevSeg.sentences) {
47559
+ touch(m_0.id, nextSeg);
47560
+ } else {
47561
+ touch(m_0.id, prevSeg);
47519
47562
  }
47520
47563
  var existing = prevById.get(m_0.id);
47521
47564
  var sentences = nextSeg.sentences;
47522
47565
  var nextIndex = Math.min((_existing$nextIndex = existing === null || existing === void 0 ? void 0 : existing.nextIndex) !== null && _existing$nextIndex !== void 0 ? _existing$nextIndex : 0, sentences.length);
47523
47566
  var stopped = (_existing$stopped = existing === null || existing === void 0 ? void 0 : existing.stopped) !== null && _existing$stopped !== void 0 ? _existing$stopped : false;
47524
- var reuseExisting = !!existing && existing.status === m_0.status && existing.sentences === sentences && // same array ref -> no change
47525
- existing.nextIndex === nextIndex && existing.stopped === stopped;
47526
- if (reuseExisting) {
47567
+ var reuse = !!existing && existing.status === m_0.status && existing.sentences === sentences && existing.nextIndex === nextIndex && existing.stopped === stopped;
47568
+ if (reuse) {
47527
47569
  next.push(existing);
47528
47570
  } else {
47529
47571
  next.push({
@@ -47536,32 +47578,69 @@ var useMessageAudio = function(_ref) {
47536
47578
  changed = true;
47537
47579
  }
47538
47580
  }
47539
- } catch (err) {
47540
- _didIteratorError = true;
47541
- _iteratorError = err;
47542
- } finally{
47581
+ var unfinished = [];
47582
+ var finished = [];
47583
+ for(var i_1 = 0; i_1 < next.length; i_1++){
47584
+ var m_1 = next[i_1];
47585
+ if (!m_1.stopped && (m_1.status === "in_progress" || m_1.nextIndex < m_1.sentences.length)) {
47586
+ unfinished.push(m_1);
47587
+ } else {
47588
+ finished.push(m_1);
47589
+ }
47590
+ }
47591
+ var prunedFinished = finished.length > KEEP_FINISHED_MESSAGES ? finished.slice(finished.length - KEEP_FINISHED_MESSAGES) : finished;
47592
+ var combined = unfinished.concat(prunedFinished);
47593
+ if (!changed) {
47594
+ if (combined.length !== prev.length) changed = true;
47595
+ else {
47596
+ for(var i_2 = 0; i_2 < combined.length; i_2++){
47597
+ if (combined[i_2] !== prev[i_2]) {
47598
+ changed = true;
47599
+ break;
47600
+ }
47601
+ }
47602
+ }
47603
+ }
47604
+ var idsInQueue = new Set(combined.map(function(m_2) {
47605
+ return m_2.id;
47606
+ }));
47607
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
47543
47608
  try {
47544
- if (!_iteratorNormalCompletion && _iterator.return != null) {
47545
- _iterator.return();
47609
+ for(var _iterator = Array.from(segCache.keys())[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
47610
+ var id_0 = _step.value;
47611
+ if (!idsInQueue.has(id_0)) segCache.delete(id_0);
47546
47612
  }
47613
+ } catch (err) {
47614
+ _didIteratorError = true;
47615
+ _iteratorError = err;
47547
47616
  } finally{
47548
- if (_didIteratorError) {
47549
- throw _iteratorError;
47617
+ try {
47618
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
47619
+ _iterator.return();
47620
+ }
47621
+ } finally{
47622
+ if (_didIteratorError) {
47623
+ throw _iteratorError;
47624
+ }
47550
47625
  }
47551
47626
  }
47627
+ evictLRU();
47628
+ return changed ? combined : prev;
47629
+ });
47630
+ mirrorTimerRef.current = null;
47631
+ if (pendingMirrorRef.current) {
47632
+ pendingMirrorRef.current = false;
47633
+ mirrorTimerRef.current = window.setTimeout(run, THROTTLE_MS);
47552
47634
  }
47553
- if (next.length !== prev.length) {
47554
- changed = true;
47555
- } else {
47556
- for(var i = 0; i < next.length; i++){
47557
- if (next[i] !== prev[i]) {
47558
- changed = true;
47559
- break;
47560
- }
47561
- }
47635
+ };
47636
+ mirrorTimerRef.current = window.setTimeout(run, THROTTLE_MS);
47637
+ return function() {
47638
+ if (mirrorTimerRef.current != null) {
47639
+ clearTimeout(mirrorTimerRef.current);
47640
+ mirrorTimerRef.current = null;
47562
47641
  }
47563
- return changed ? next : prev;
47564
- });
47642
+ pendingMirrorRef.current = false;
47643
+ };
47565
47644
  }, [
47566
47645
  messagesProps.messages
47567
47646
  ]);
@@ -47573,15 +47652,14 @@ var useMessageAudio = function(_ref) {
47573
47652
  audioPlayer.load("".concat(superinterfaceContext.baseUrl, "/audio-runtimes/tts?").concat(searchParams), {
47574
47653
  format: "mp3",
47575
47654
  autoplay: isAudioPlayed,
47576
- // first call false; then true for snappier chaining
47577
47655
  html5: isHtmlAudioSupported,
47578
47656
  onplay: onPlay,
47579
47657
  onstop: onStop,
47580
47658
  onload: function() {
47581
47659
  var current = currentSentenceRef.current;
47582
47660
  if (!current) return;
47583
- var msg = audioQueueRef.current.find(function(m_1) {
47584
- return m_1.id === current.messageId;
47661
+ var msg = audioQueueRef.current.find(function(m_3) {
47662
+ return m_3.id === current.messageId;
47585
47663
  });
47586
47664
  if (!msg) return;
47587
47665
  var nextSentence = msg.sentences[msg.nextIndex];
@@ -47616,42 +47694,23 @@ var useMessageAudio = function(_ref) {
47616
47694
  if (audioPlayer.playing) return;
47617
47695
  if (pickLockRef.current) return;
47618
47696
  var candidate = null;
47619
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
47620
- try {
47621
- for(var _iterator = audioQueue[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
47622
- var msg_0 = _step.value;
47623
- if (msg_0.stopped) continue;
47624
- var sentence = msg_0.sentences[msg_0.nextIndex];
47625
- while(sentence && !/\S/.test(sentence)){
47626
- msg_0.nextIndex++;
47627
- sentence = msg_0.sentences[msg_0.nextIndex];
47628
- }
47629
- if (!sentence) continue;
47630
- var isFull = isOptimistic({
47631
- id: msg_0.id
47632
- }) || msg_0.status !== "in_progress" || fullSentenceRegex.test(sentence);
47633
- if (isFull) {
47634
- candidate = {
47635
- messageId: msg_0.id,
47636
- sentence: sentence,
47637
- index: msg_0.nextIndex,
47638
- ownerStatus: msg_0.status
47639
- };
47640
- break;
47641
- }
47642
- }
47643
- } catch (err) {
47644
- _didIteratorError = true;
47645
- _iteratorError = err;
47646
- } finally{
47647
- try {
47648
- if (!_iteratorNormalCompletion && _iterator.return != null) {
47649
- _iterator.return();
47650
- }
47651
- } finally{
47652
- if (_didIteratorError) {
47653
- throw _iteratorError;
47654
- }
47697
+ for(var mIdx = 0; mIdx < audioQueue.length; mIdx++){
47698
+ var msg_0 = audioQueue[mIdx];
47699
+ if (msg_0.stopped) continue;
47700
+ var idx = msg_0.nextIndex;
47701
+ var sentence = msg_0.sentences[idx];
47702
+ if (!sentence) continue;
47703
+ var isFull = isOptimistic({
47704
+ id: msg_0.id
47705
+ }) || msg_0.status !== "in_progress" || fullSentenceRegex.test(sentence);
47706
+ if (isFull) {
47707
+ candidate = {
47708
+ messageId: msg_0.id,
47709
+ sentence: sentence,
47710
+ index: idx,
47711
+ ownerStatus: msg_0.status
47712
+ };
47713
+ break;
47655
47714
  }
47656
47715
  }
47657
47716
  if (!candidate) return;
@@ -47662,10 +47721,10 @@ var useMessageAudio = function(_ref) {
47662
47721
  index: candidate.index
47663
47722
  };
47664
47723
  setAudioQueue(function(prev_0) {
47665
- return prev_0.map(function(m_2) {
47666
- return m_2.id === candidate.messageId ? _objectSpread47(_objectSpread47({}, m_2), {}, {
47667
- nextIndex: m_2.nextIndex + 1
47668
- }) : m_2;
47724
+ return prev_0.map(function(m_4) {
47725
+ return m_4.id === candidate.messageId ? _objectSpread47(_objectSpread47({}, m_4), {}, {
47726
+ nextIndex: candidate.index + 1
47727
+ }) : m_4;
47669
47728
  });
47670
47729
  });
47671
47730
  play({
@@ -47675,10 +47734,10 @@ var useMessageAudio = function(_ref) {
47675
47734
  },
47676
47735
  onStop: function() {
47677
47736
  setAudioQueue(function(prev_1) {
47678
- return prev_1.map(function(m_3) {
47679
- return m_3.id === candidate.messageId ? _objectSpread47(_objectSpread47({}, m_3), {}, {
47737
+ return prev_1.map(function(m_5) {
47738
+ return m_5.id === candidate.messageId ? _objectSpread47(_objectSpread47({}, m_5), {}, {
47680
47739
  stopped: true
47681
- }) : m_3;
47740
+ }) : m_5;
47682
47741
  });
47683
47742
  });
47684
47743
  setIsPlaying(false);
@@ -47689,10 +47748,10 @@ var useMessageAudio = function(_ref) {
47689
47748
  setIsPlaying(false);
47690
47749
  currentSentenceRef.current = null;
47691
47750
  pickLockRef.current = false;
47692
- var hasPending = audioQueueRef.current.some(function(m_4) {
47693
- if (m_4.stopped) return false;
47694
- var hasMore = m_4.nextIndex < m_4.sentences.length;
47695
- var streaming = m_4.status === "in_progress";
47751
+ var hasPending = audioQueueRef.current.some(function(m_6) {
47752
+ if (m_6.stopped) return false;
47753
+ var hasMore = m_6.nextIndex < m_6.sentences.length;
47754
+ var streaming = m_6.status === "in_progress";
47696
47755
  return hasMore || streaming;
47697
47756
  });
47698
47757
  if (!hasPending) _onEnd();
@@ -47708,9 +47767,9 @@ var useMessageAudio = function(_ref) {
47708
47767
  ]);
47709
47768
  (0, import_react67.useEffect)(function() {
47710
47769
  if (isHtmlAudioSupported) {
47711
- var _Howler$_howls$;
47712
- if (!(import_howler.Howler !== null && import_howler.Howler !== void 0 && (_Howler$_howls$ = import_howler.Howler._howls[0]) !== null && _Howler$_howls$ !== void 0 && (_Howler$_howls$ = _Howler$_howls$._sounds[0]) !== null && _Howler$_howls$ !== void 0 && _Howler$_howls$._node)) return;
47713
- import_howler.Howler._howls[0]._sounds[0]._node.crossOrigin = "anonymous";
47770
+ var _Howler$_howls;
47771
+ var node = import_howler.Howler === null || import_howler.Howler === void 0 || (_Howler$_howls = import_howler.Howler._howls) === null || _Howler$_howls === void 0 || (_Howler$_howls = _Howler$_howls[0]) === null || _Howler$_howls === void 0 || (_Howler$_howls = _Howler$_howls._sounds) === null || _Howler$_howls === void 0 || (_Howler$_howls = _Howler$_howls[0]) === null || _Howler$_howls === void 0 ? void 0 : _Howler$_howls._node;
47772
+ if (node) node.crossOrigin = "anonymous";
47714
47773
  }
47715
47774
  }, [
47716
47775
  audioPlayer
@@ -47722,14 +47781,17 @@ var useMessageAudio = function(_ref) {
47722
47781
  if (isAudioEngineInited.current) return;
47723
47782
  isAudioEngineInited.current = true;
47724
47783
  if (isHtmlAudioSupported) {
47725
- var _Howler$_howls$2;
47726
- var audioContext = new AudioContext();
47727
- setAudioEngine({
47728
- // @ts-ignore-next-line
47729
- source: audioContext.createMediaElementSource(// @ts-ignore-next-line
47730
- (_Howler$_howls$2 = import_howler.Howler._howls[0]) === null || _Howler$_howls$2 === void 0 || (_Howler$_howls$2 = _Howler$_howls$2._sounds[0]) === null || _Howler$_howls$2 === void 0 ? void 0 : _Howler$_howls$2._node),
47731
- audioContext: audioContext
47732
- });
47784
+ var _Howler$_howls2;
47785
+ var AudioCtx = window.AudioContext || window.webkitAudioContext;
47786
+ var audioContext = new AudioCtx();
47787
+ var node_0 = import_howler.Howler === null || import_howler.Howler === void 0 || (_Howler$_howls2 = import_howler.Howler._howls) === null || _Howler$_howls2 === void 0 || (_Howler$_howls2 = _Howler$_howls2[0]) === null || _Howler$_howls2 === void 0 || (_Howler$_howls2 = _Howler$_howls2._sounds) === null || _Howler$_howls2 === void 0 || (_Howler$_howls2 = _Howler$_howls2[0]) === null || _Howler$_howls2 === void 0 ? void 0 : _Howler$_howls2._node;
47788
+ if (node_0) {
47789
+ setAudioEngine({
47790
+ // @ts-ignore-next-line
47791
+ source: audioContext.createMediaElementSource(node_0),
47792
+ audioContext: audioContext
47793
+ });
47794
+ }
47733
47795
  } else {
47734
47796
  setAudioEngine({
47735
47797
  source: import_howler.Howler.masterGain,
@@ -47749,8 +47811,8 @@ var useMessageAudio = function(_ref) {
47749
47811
  audioEngine
47750
47812
  ]);
47751
47813
  var isPending = (0, import_react67.useMemo)(function() {
47752
- return isPlaying || audioQueue.some(function(m_5) {
47753
- return !m_5.stopped && (m_5.nextIndex < m_5.sentences.length || m_5.status === "in_progress");
47814
+ return isPlaying || audioQueue.some(function(m_7) {
47815
+ return !m_7.stopped && (m_7.nextIndex < m_7.sentences.length || m_7.status === "in_progress");
47754
47816
  });
47755
47817
  }, [
47756
47818
  isPlaying,