@cartesia/cartesia-js 1.0.3 → 1.2.1-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +32 -3
  3. package/dist/{chunk-BHY7MNGT.js → chunk-5SBAQNWQ.js} +1 -1
  4. package/dist/{chunk-LZO6K34D.js → chunk-CSOXALSC.js} +7 -7
  5. package/dist/{chunk-PISCPZK4.js → chunk-FLWYXP5Z.js} +1 -1
  6. package/dist/chunk-GLZYI5DM.js +43 -0
  7. package/dist/{chunk-6YQ6KDIQ.js → chunk-I5YVYTNK.js} +47 -16
  8. package/dist/{chunk-NQVZNVOU.js → chunk-LKKWJLUG.js} +1 -1
  9. package/dist/{chunk-GHY2WEOK.js → chunk-NJDRWDQ3.js} +8 -35
  10. package/dist/{chunk-ZF6HASZT.js → chunk-QWNB544W.js} +7 -3
  11. package/dist/{chunk-YFN6TFR4.js → chunk-RJICGVPL.js} +12 -4
  12. package/dist/chunk-WLEVU3HN.js +42 -0
  13. package/dist/{chunk-EUW2435M.js → chunk-WSIVWXEI.js} +49 -25
  14. package/dist/index.cjs +162 -76
  15. package/dist/index.d.cts +2 -1
  16. package/dist/index.d.ts +2 -1
  17. package/dist/index.js +10 -9
  18. package/dist/lib/client.js +2 -2
  19. package/dist/lib/constants.js +1 -1
  20. package/dist/lib/index.cjs +157 -71
  21. package/dist/lib/index.d.cts +2 -0
  22. package/dist/lib/index.d.ts +2 -0
  23. package/dist/lib/index.js +9 -8
  24. package/dist/react/index.cjs +165 -76
  25. package/dist/react/index.js +14 -10
  26. package/dist/react/utils.js +2 -2
  27. package/dist/tts/index.cjs +114 -69
  28. package/dist/tts/index.d.cts +8 -1
  29. package/dist/tts/index.d.ts +8 -1
  30. package/dist/tts/index.js +6 -6
  31. package/dist/tts/player.cjs +13 -27
  32. package/dist/tts/player.js +4 -4
  33. package/dist/tts/source.cjs +54 -37
  34. package/dist/tts/source.d.cts +9 -0
  35. package/dist/tts/source.d.ts +9 -0
  36. package/dist/tts/source.js +2 -2
  37. package/dist/tts/utils.js +3 -3
  38. package/dist/tts/websocket.cjs +99 -69
  39. package/dist/tts/websocket.d.cts +15 -9
  40. package/dist/tts/websocket.d.ts +15 -9
  41. package/dist/tts/websocket.js +5 -5
  42. package/dist/types/index.d.cts +42 -3
  43. package/dist/types/index.d.ts +42 -3
  44. package/dist/voice-changer/index.cjs +143 -0
  45. package/dist/voice-changer/index.d.cts +9 -0
  46. package/dist/voice-changer/index.d.ts +9 -0
  47. package/dist/voice-changer/index.js +9 -0
  48. package/dist/voices/index.cjs +10 -2
  49. package/dist/voices/index.d.cts +2 -1
  50. package/dist/voices/index.d.ts +2 -1
  51. package/dist/voices/index.js +3 -3
  52. package/package.json +8 -16
  53. package/src/lib/index.ts +3 -0
  54. package/src/react/index.ts +4 -0
  55. package/src/tts/index.ts +16 -1
  56. package/src/tts/source.ts +35 -0
  57. package/src/tts/websocket.ts +33 -2
  58. package/src/types/index.ts +60 -2
  59. package/src/voice-changer/index.ts +37 -0
  60. package/src/voices/index.ts +12 -3
  61. package/.turbo/turbo-build.log +0 -75
  62. package/dist/chunk-NWCW6C7H.js +0 -25
  63. package/tsconfig.json +0 -3
@@ -9,6 +9,9 @@ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
9
  var __getProtoOf = Object.getPrototypeOf;
10
10
  var __hasOwnProp = Object.prototype.hasOwnProperty;
11
11
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
12
+ var __typeError = (msg) => {
13
+ throw TypeError(msg);
14
+ };
12
15
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
16
  var __spreadValues = (a, b) => {
14
17
  for (var prop in b || (b = {}))
@@ -22,18 +25,6 @@ var __spreadValues = (a, b) => {
22
25
  return a;
23
26
  };
24
27
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
25
- var __objRest = (source, exclude) => {
26
- var target = {};
27
- for (var prop in source)
28
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
29
- target[prop] = source[prop];
30
- if (source != null && __getOwnPropSymbols)
31
- for (var prop of __getOwnPropSymbols(source)) {
32
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
33
- target[prop] = source[prop];
34
- }
35
- return target;
36
- };
37
28
  var __export = (target, all) => {
38
29
  for (var name in all)
39
30
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -55,28 +46,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
55
46
  mod
56
47
  ));
57
48
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
58
- var __accessCheck = (obj, member, msg) => {
59
- if (!member.has(obj))
60
- throw TypeError("Cannot " + msg);
61
- };
62
- var __privateGet = (obj, member, getter) => {
63
- __accessCheck(obj, member, "read from private field");
64
- return getter ? getter.call(obj) : member.get(obj);
65
- };
66
- var __privateAdd = (obj, member, value) => {
67
- if (member.has(obj))
68
- throw TypeError("Cannot add the same private member more than once");
69
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
70
- };
71
- var __privateSet = (obj, member, value, setter) => {
72
- __accessCheck(obj, member, "write to private field");
73
- setter ? setter.call(obj, value) : member.set(obj, value);
74
- return value;
75
- };
76
- var __privateMethod = (obj, member, method) => {
77
- __accessCheck(obj, member, "access private method");
78
- return method;
79
- };
49
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
50
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
51
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
52
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
53
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
80
54
  var __async = (__this, __arguments, generator) => {
81
55
  return new Promise((resolve, reject) => {
82
56
  var fulfilled = (value) => {
@@ -158,7 +132,7 @@ var ENCODING_MAP = {
158
132
  pcm_alaw: { arrayType: Uint8Array, bytesPerElement: 1 },
159
133
  pcm_mulaw: { arrayType: Uint8Array, bytesPerElement: 1 }
160
134
  };
161
- var _emitter, _buffer, _readIndex, _writeIndex, _closed, _sampleRate, _encoding, _container, _createBuffer, createBuffer_fn;
135
+ var _emitter, _buffer, _readIndex, _writeIndex, _closed, _sampleRate, _encoding, _container, _Source_instances, createBuffer_fn;
162
136
  var Source = class {
163
137
  /**
164
138
  * Create a new Source.
@@ -171,21 +145,15 @@ var Source = class {
171
145
  encoding,
172
146
  container
173
147
  }) {
174
- /**
175
- * Create a new buffer for the source.
176
- *
177
- * @param size - The size of the buffer to create.
178
- * @returns The new buffer as a TypedArray based on the encoding.
179
- */
180
- __privateAdd(this, _createBuffer);
148
+ __privateAdd(this, _Source_instances);
181
149
  __privateAdd(this, _emitter, new import_emittery.default());
182
- __privateAdd(this, _buffer, void 0);
150
+ __privateAdd(this, _buffer);
183
151
  __privateAdd(this, _readIndex, 0);
184
152
  __privateAdd(this, _writeIndex, 0);
185
153
  __privateAdd(this, _closed, false);
186
- __privateAdd(this, _sampleRate, void 0);
187
- __privateAdd(this, _encoding, void 0);
188
- __privateAdd(this, _container, void 0);
154
+ __privateAdd(this, _sampleRate);
155
+ __privateAdd(this, _encoding);
156
+ __privateAdd(this, _container);
189
157
  this.on = __privateGet(this, _emitter).on.bind(__privateGet(this, _emitter));
190
158
  this.once = __privateGet(this, _emitter).once.bind(__privateGet(this, _emitter));
191
159
  this.events = __privateGet(this, _emitter).events.bind(__privateGet(this, _emitter));
@@ -193,7 +161,7 @@ var Source = class {
193
161
  __privateSet(this, _sampleRate, sampleRate);
194
162
  __privateSet(this, _encoding, encoding);
195
163
  __privateSet(this, _container, container);
196
- __privateSet(this, _buffer, __privateMethod(this, _createBuffer, createBuffer_fn).call(this, 1024));
164
+ __privateSet(this, _buffer, __privateMethod(this, _Source_instances, createBuffer_fn).call(this, 1024));
197
165
  }
198
166
  get sampleRate() {
199
167
  return __privateGet(this, _sampleRate);
@@ -217,7 +185,7 @@ var Source = class {
217
185
  while (newCapacity < requiredCapacity) {
218
186
  newCapacity *= 2;
219
187
  }
220
- const newBuffer = __privateMethod(this, _createBuffer, createBuffer_fn).call(this, newCapacity);
188
+ const newBuffer = __privateMethod(this, _Source_instances, createBuffer_fn).call(this, newCapacity);
221
189
  newBuffer.set(__privateGet(this, _buffer));
222
190
  __privateSet(this, _buffer, newBuffer);
223
191
  }
@@ -250,6 +218,37 @@ var Source = class {
250
218
  return read;
251
219
  });
252
220
  }
221
+ /**
222
+ * Seek in the buffer.
223
+ *
224
+ * @param offset The offset to seek to.
225
+ * @param whence The position to seek from.
226
+ * @returns The new position in the buffer.
227
+ * @throws {Error} If the seek is invalid.
228
+ */
229
+ seek(offset, whence) {
230
+ return __async(this, null, function* () {
231
+ let position = __privateGet(this, _readIndex);
232
+ switch (whence) {
233
+ case "start":
234
+ position = offset;
235
+ break;
236
+ case "current":
237
+ position += offset;
238
+ break;
239
+ case "end":
240
+ position = __privateGet(this, _writeIndex) + offset;
241
+ break;
242
+ default:
243
+ throw new Error(`Invalid seek mode: ${whence}`);
244
+ }
245
+ if (position < 0 || position > __privateGet(this, _writeIndex)) {
246
+ throw new Error("Seek out of bounds");
247
+ }
248
+ __privateSet(this, _readIndex, position);
249
+ return position;
250
+ });
251
+ }
253
252
  /**
254
253
  * Get the number of samples in a given duration.
255
254
  *
@@ -291,7 +290,13 @@ _closed = new WeakMap();
291
290
  _sampleRate = new WeakMap();
292
291
  _encoding = new WeakMap();
293
292
  _container = new WeakMap();
294
- _createBuffer = new WeakSet();
293
+ _Source_instances = new WeakSet();
294
+ /**
295
+ * Create a new buffer for the source.
296
+ *
297
+ * @param size - The size of the buffer to create.
298
+ * @returns The new buffer as a TypedArray based on the encoding.
299
+ */
295
300
  createBuffer_fn = function(size) {
296
301
  const { arrayType: ArrayType } = ENCODING_MAP[__privateGet(this, _encoding)];
297
302
  return new ArrayType(size);
@@ -367,7 +372,7 @@ function getEmitteryCallbacks(emitter) {
367
372
  }
368
373
 
369
374
  // src/tts/websocket.ts
370
- var _isConnected, _sampleRate2, _container2, _encoding2, _generateId, generateId_fn;
375
+ var _isConnected, _sampleRate2, _container2, _encoding2, _WebSocket_instances, generateId_fn;
371
376
  var WebSocket = class extends Client {
372
377
  /**
373
378
  * Create a new WebSocket client.
@@ -376,19 +381,11 @@ var WebSocket = class extends Client {
376
381
  */
377
382
  constructor({ sampleRate, container, encoding }, ...args) {
378
383
  super(...args);
379
- /**
380
- * Generate a unique ID suitable for a streaming context.
381
- *
382
- * Not suitable for security purposes or as a primary key, since
383
- * it lacks the amount of entropy required for those use cases.
384
- *
385
- * @returns A unique ID.
386
- */
387
- __privateAdd(this, _generateId);
384
+ __privateAdd(this, _WebSocket_instances);
388
385
  __privateAdd(this, _isConnected, false);
389
- __privateAdd(this, _sampleRate2, void 0);
390
- __privateAdd(this, _container2, void 0);
391
- __privateAdd(this, _encoding2, void 0);
386
+ __privateAdd(this, _sampleRate2);
387
+ __privateAdd(this, _container2);
388
+ __privateAdd(this, _encoding2);
392
389
  __privateSet(this, _sampleRate2, sampleRate);
393
390
  __privateSet(this, _container2, container != null ? container : "raw");
394
391
  __privateSet(this, _encoding2, encoding != null ? encoding : "pcm_f32le");
@@ -396,7 +393,7 @@ var WebSocket = class extends Client {
396
393
  /**
397
394
  * Send a message over the WebSocket to start a stream.
398
395
  *
399
- * @param inputs - Stream options. Defined in the StreamRequest type.
396
+ * @param inputs - Generation parameters. Defined in the StreamRequest type.
400
397
  * @param options - Options for the stream.
401
398
  * @param options.timeout - The maximum time to wait for a chunk before cancelling the stream.
402
399
  * If set to `0`, the stream will not time out.
@@ -404,14 +401,13 @@ var WebSocket = class extends Client {
404
401
  * @returns An Emittery instance that emits messages from the WebSocket.
405
402
  * @returns An abort function that can be called to cancel the stream.
406
403
  */
407
- send(_a, { timeout = 0 } = {}) {
408
- var inputs = __objRest(_a, []);
409
- var _a2, _b, _c, _d;
404
+ send(inputs, { timeout = 0 } = {}) {
405
+ var _a, _b, _c, _d;
410
406
  if (!__privateGet(this, _isConnected)) {
411
407
  throw new Error("Not connected to WebSocket. Call .connect() first.");
412
408
  }
413
409
  if (!inputs.context_id) {
414
- inputs.context_id = __privateMethod(this, _generateId, generateId_fn).call(this);
410
+ inputs.context_id = __privateMethod(this, _WebSocket_instances, generateId_fn).call(this);
415
411
  }
416
412
  if (!inputs.output_format) {
417
413
  inputs.output_format = {
@@ -420,7 +416,7 @@ var WebSocket = class extends Client {
420
416
  sample_rate: __privateGet(this, _sampleRate2)
421
417
  };
422
418
  }
423
- (_a2 = this.socket) == null ? void 0 : _a2.send(
419
+ (_a = this.socket) == null ? void 0 : _a.send(
424
420
  JSON.stringify(__spreadValues({}, inputs))
425
421
  );
426
422
  const emitter = new import_emittery2.default();
@@ -490,6 +486,32 @@ var WebSocket = class extends Client {
490
486
  stop: streamCompleteController.abort.bind(streamCompleteController)
491
487
  });
492
488
  }
489
+ /**
490
+ * Continue a stream.
491
+ *
492
+ * @param inputs - Generation parameters. Defined in the StreamRequest type, but must include a `context_id` field. `continue` is set to true by default.
493
+ */
494
+ continue(inputs) {
495
+ var _a;
496
+ if (!__privateGet(this, _isConnected)) {
497
+ throw new Error("Not connected to WebSocket. Call .connect() first.");
498
+ }
499
+ if (!inputs.context_id) {
500
+ throw new Error("context_id is required to continue a context.");
501
+ }
502
+ if (!inputs.output_format) {
503
+ inputs.output_format = {
504
+ container: __privateGet(this, _container2),
505
+ encoding: __privateGet(this, _encoding2),
506
+ sample_rate: __privateGet(this, _sampleRate2)
507
+ };
508
+ }
509
+ (_a = this.socket) == null ? void 0 : _a.send(
510
+ JSON.stringify(__spreadValues({
511
+ continue: true
512
+ }, inputs))
513
+ );
514
+ }
493
515
  /**
494
516
  * Authenticate and connect to a Cartesia streaming WebSocket.
495
517
  *
@@ -565,7 +587,15 @@ _isConnected = new WeakMap();
565
587
  _sampleRate2 = new WeakMap();
566
588
  _container2 = new WeakMap();
567
589
  _encoding2 = new WeakMap();
568
- _generateId = new WeakSet();
590
+ _WebSocket_instances = new WeakSet();
591
+ /**
592
+ * Generate a unique ID suitable for a streaming context.
593
+ *
594
+ * Not suitable for security purposes or as a primary key, since
595
+ * it lacks the amount of entropy required for those use cases.
596
+ *
597
+ * @returns A unique ID.
598
+ */
569
599
  generateId_fn = function() {
570
600
  return (0, import_human_id.humanId)({
571
601
  separator: "-",
@@ -586,6 +616,53 @@ var TTS = class extends Client {
586
616
  baseUrl: this.baseUrl
587
617
  });
588
618
  }
619
+ /**
620
+ * Generate audio bytes from text.
621
+ *
622
+ * @param options - The options for the request.
623
+ * @returns {Promise<ArrayBuffer>} A promise that resolves to an ArrayBuffer containing the audio bytes.
624
+ */
625
+ bytes(options) {
626
+ return __async(this, null, function* () {
627
+ const response = yield this._fetch("/tts/bytes", {
628
+ method: "POST",
629
+ body: JSON.stringify(options)
630
+ });
631
+ return response.arrayBuffer();
632
+ });
633
+ }
634
+ };
635
+
636
+ // src/voice-changer/index.ts
637
+ var VoiceChanger = class extends Client {
638
+ bytes(options) {
639
+ return __async(this, null, function* () {
640
+ const formData = new FormData();
641
+ formData.append("clip", options.clip);
642
+ formData.append("voice[id]", options.voice.id);
643
+ const fmt = options.output_format;
644
+ formData.append("output_format[container]", fmt.container);
645
+ if ("encoding" in fmt) {
646
+ formData.append("output_format[encoding]", fmt.encoding);
647
+ }
648
+ if ("bit_rate" in fmt) {
649
+ formData.append("output_format[bit_rate]", fmt.bit_rate.toString());
650
+ }
651
+ if ("sample_rate" in fmt) {
652
+ formData.append("output_format[sample_rate]", fmt.sample_rate.toString());
653
+ }
654
+ const response = yield this._fetch("/voice-changer/bytes", {
655
+ method: "POST",
656
+ body: formData
657
+ });
658
+ if (!response.ok) {
659
+ throw new Error(
660
+ `Voice changer error! status: ${response.status}, message: ${yield response.text()}`
661
+ );
662
+ }
663
+ return { buffer: yield response.arrayBuffer() };
664
+ });
665
+ }
589
666
  };
590
667
 
591
668
  // src/voices/index.ts
@@ -639,10 +716,18 @@ var Voices = class extends Client {
639
716
  }
640
717
  mix(options) {
641
718
  return __async(this, null, function* () {
642
- const request = options;
643
719
  const response = yield this._fetch("/voices/mix", {
644
720
  method: "POST",
645
- body: JSON.stringify(request)
721
+ body: JSON.stringify(options)
722
+ });
723
+ return response.json();
724
+ });
725
+ }
726
+ localize(options) {
727
+ return __async(this, null, function* () {
728
+ const response = yield this._fetch("/voices/localize", {
729
+ method: "POST",
730
+ body: JSON.stringify(options)
646
731
  });
647
732
  return response.json();
648
733
  });
@@ -655,11 +740,12 @@ var Cartesia = class extends Client {
655
740
  super(options);
656
741
  this.tts = new TTS(options);
657
742
  this.voices = new Voices(options);
743
+ this.voiceChanger = new VoiceChanger(options);
658
744
  }
659
745
  };
660
746
 
661
747
  // src/tts/player.ts
662
- var _context, _startNextPlaybackAt, _bufferDuration, _playBuffer, playBuffer_fn;
748
+ var _context, _startNextPlaybackAt, _bufferDuration, _Player_instances, playBuffer_fn;
663
749
  var Player = class {
664
750
  /**
665
751
  * Create a new Player.
@@ -668,10 +754,10 @@ var Player = class {
668
754
  * @param options.bufferDuration - The duration of the audio buffer to play.
669
755
  */
670
756
  constructor({ bufferDuration }) {
671
- __privateAdd(this, _playBuffer);
757
+ __privateAdd(this, _Player_instances);
672
758
  __privateAdd(this, _context, null);
673
759
  __privateAdd(this, _startNextPlaybackAt, 0);
674
- __privateAdd(this, _bufferDuration, void 0);
760
+ __privateAdd(this, _bufferDuration);
675
761
  __privateSet(this, _bufferDuration, bufferDuration);
676
762
  }
677
763
  /**
@@ -691,7 +777,7 @@ var Player = class {
691
777
  while (true) {
692
778
  const read = yield source.read(buffer);
693
779
  const playableAudio = buffer.subarray(0, read);
694
- plays.push(__privateMethod(this, _playBuffer, playBuffer_fn).call(this, playableAudio, source.sampleRate));
780
+ plays.push(__privateMethod(this, _Player_instances, playBuffer_fn).call(this, playableAudio, source.sampleRate));
695
781
  if (read < buffer.length) {
696
782
  break;
697
783
  }
@@ -760,7 +846,7 @@ var Player = class {
760
846
  _context = new WeakMap();
761
847
  _startNextPlaybackAt = new WeakMap();
762
848
  _bufferDuration = new WeakMap();
763
- _playBuffer = new WeakSet();
849
+ _Player_instances = new WeakSet();
764
850
  playBuffer_fn = function(buf, sampleRate) {
765
851
  return __async(this, null, function* () {
766
852
  if (!__privateGet(this, _context)) {
@@ -943,6 +1029,9 @@ function useTTS({
943
1029
  if (player.current) {
944
1030
  yield player.current.stop();
945
1031
  }
1032
+ if (playbackStatus === "finished") {
1033
+ websocketReturn.current.source.seek(0, "start");
1034
+ }
946
1035
  setPlaybackStatus("playing");
947
1036
  const unsubscribes = [];
948
1037
  unsubscribes.push(
@@ -1,22 +1,23 @@
1
1
  import {
2
2
  Cartesia
3
- } from "../chunk-ZF6HASZT.js";
4
- import "../chunk-YFN6TFR4.js";
3
+ } from "../chunk-QWNB544W.js";
4
+ import "../chunk-WLEVU3HN.js";
5
+ import "../chunk-RJICGVPL.js";
5
6
  import {
6
7
  pingServer
7
- } from "../chunk-NQVZNVOU.js";
8
- import "../chunk-NWCW6C7H.js";
9
- import "../chunk-EUW2435M.js";
10
- import "../chunk-PISCPZK4.js";
8
+ } from "../chunk-LKKWJLUG.js";
9
+ import "../chunk-GLZYI5DM.js";
10
+ import "../chunk-WSIVWXEI.js";
11
+ import "../chunk-FLWYXP5Z.js";
11
12
  import "../chunk-2BFEKY3F.js";
12
13
  import {
13
14
  Player
14
- } from "../chunk-LZO6K34D.js";
15
- import "../chunk-BHY7MNGT.js";
16
- import "../chunk-6YQ6KDIQ.js";
15
+ } from "../chunk-CSOXALSC.js";
16
+ import "../chunk-5SBAQNWQ.js";
17
+ import "../chunk-I5YVYTNK.js";
17
18
  import {
18
19
  __async
19
- } from "../chunk-GHY2WEOK.js";
20
+ } from "../chunk-NJDRWDQ3.js";
20
21
 
21
22
  // src/react/index.ts
22
23
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
@@ -176,6 +177,9 @@ function useTTS({
176
177
  if (player.current) {
177
178
  yield player.current.stop();
178
179
  }
180
+ if (playbackStatus === "finished") {
181
+ websocketReturn.current.source.seek(0, "start");
182
+ }
179
183
  setPlaybackStatus("playing");
180
184
  const unsubscribes = [];
181
185
  unsubscribes.push(
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  pingServer
3
- } from "../chunk-NQVZNVOU.js";
4
- import "../chunk-GHY2WEOK.js";
3
+ } from "../chunk-LKKWJLUG.js";
4
+ import "../chunk-NJDRWDQ3.js";
5
5
  export {
6
6
  pingServer
7
7
  };