@cartesia/cartesia-js 0.0.4-alpha.0 → 1.0.0-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 (89) hide show
  1. package/.turbo/turbo-build.log +63 -45
  2. package/CHANGELOG.md +12 -0
  3. package/README.md +123 -16
  4. package/dist/chunk-36JBKJUN.js +119 -0
  5. package/dist/chunk-3F5E46FT.js +212 -0
  6. package/dist/{chunk-XPIMIAAE.js → chunk-3FL2SNIR.js} +1 -1
  7. package/dist/chunk-JGP5BIUV.js +34 -0
  8. package/dist/chunk-KWBSQZTY.js +25 -0
  9. package/dist/chunk-PQ6CIPFW.js +120 -0
  10. package/dist/chunk-RO7TY474.js +81 -0
  11. package/dist/chunk-T3RG6WV4.js +22 -0
  12. package/dist/{chunk-R4P7LWVZ.js → chunk-WIFMLPT5.js} +31 -6
  13. package/dist/chunk-WVTITUXX.js +58 -0
  14. package/dist/chunk-XHTDPLFR.js +19 -0
  15. package/dist/index.cjs +425 -166
  16. package/dist/index.d.cts +7 -3
  17. package/dist/index.d.ts +7 -3
  18. package/dist/index.js +13 -6
  19. package/dist/lib/client.cjs +49 -1
  20. package/dist/lib/client.d.cts +2 -0
  21. package/dist/lib/client.d.ts +2 -0
  22. package/dist/lib/client.js +3 -3
  23. package/dist/lib/constants.cjs +15 -8
  24. package/dist/lib/constants.d.cts +4 -4
  25. package/dist/lib/constants.d.ts +4 -4
  26. package/dist/lib/constants.js +6 -6
  27. package/dist/lib/index.cjs +310 -171
  28. package/dist/lib/index.d.cts +6 -2
  29. package/dist/lib/index.d.ts +6 -2
  30. package/dist/lib/index.js +9 -6
  31. package/dist/react/index.cjs +573 -290
  32. package/dist/react/index.d.cts +20 -14
  33. package/dist/react/index.d.ts +20 -14
  34. package/dist/react/index.js +157 -105
  35. package/dist/react/utils.js +2 -2
  36. package/dist/tts/index.cjs +496 -0
  37. package/dist/tts/index.d.cts +17 -0
  38. package/dist/tts/index.d.ts +17 -0
  39. package/dist/tts/index.js +12 -0
  40. package/dist/tts/player.cjs +198 -0
  41. package/dist/tts/player.d.cts +43 -0
  42. package/dist/tts/player.d.ts +43 -0
  43. package/dist/tts/player.js +8 -0
  44. package/dist/tts/source.cjs +181 -0
  45. package/dist/tts/source.d.cts +53 -0
  46. package/dist/tts/source.d.ts +53 -0
  47. package/dist/tts/source.js +7 -0
  48. package/dist/{audio → tts}/utils.cjs +25 -60
  49. package/dist/tts/utils.d.cts +67 -0
  50. package/dist/tts/utils.d.ts +67 -0
  51. package/dist/{audio → tts}/utils.js +2 -7
  52. package/dist/tts/websocket.cjs +479 -0
  53. package/dist/tts/websocket.d.cts +53 -0
  54. package/dist/tts/websocket.d.ts +53 -0
  55. package/dist/tts/websocket.js +11 -0
  56. package/dist/types/index.d.cts +50 -1
  57. package/dist/types/index.d.ts +50 -1
  58. package/dist/voices/index.cjs +157 -0
  59. package/dist/voices/index.d.cts +12 -0
  60. package/dist/voices/index.d.ts +12 -0
  61. package/dist/voices/index.js +9 -0
  62. package/package.json +2 -1
  63. package/src/index.ts +1 -0
  64. package/src/lib/client.ts +15 -1
  65. package/src/lib/constants.ts +15 -4
  66. package/src/lib/index.ts +6 -3
  67. package/src/react/index.ts +176 -110
  68. package/src/tts/index.ts +17 -0
  69. package/src/tts/player.ts +110 -0
  70. package/src/tts/source.ts +115 -0
  71. package/src/tts/utils.ts +150 -0
  72. package/src/tts/websocket.ts +214 -0
  73. package/src/types/index.ts +63 -0
  74. package/src/voices/index.ts +47 -0
  75. package/dist/audio/index.cjs +0 -404
  76. package/dist/audio/index.d.cts +0 -5
  77. package/dist/audio/index.d.ts +0 -5
  78. package/dist/audio/index.js +0 -10
  79. package/dist/audio/utils.d.cts +0 -5
  80. package/dist/audio/utils.d.ts +0 -5
  81. package/dist/chunk-4MHF74A7.js +0 -272
  82. package/dist/chunk-5TSWLYOW.js +0 -113
  83. package/dist/chunk-MJIFZWHS.js +0 -18
  84. package/dist/chunk-OVI3W3GG.js +0 -12
  85. package/dist/chunk-S6A27RQL.js +0 -18
  86. package/dist/index-C2_3XFxn.d.cts +0 -163
  87. package/dist/index-DgwnZezj.d.ts +0 -163
  88. package/src/audio/index.ts +0 -297
  89. package/src/audio/utils.ts +0 -220
@@ -1,57 +1,75 @@
1
1
  $ tsup src/ --format cjs,esm --dts
2
- CLI Building entry: src/index.ts, src/audio/index.ts, src/audio/utils.ts, src/lib/client.ts, src/lib/constants.ts, src/lib/index.ts, src/react/index.ts, src/react/utils.ts, src/types/index.ts
2
+ CLI Building entry: src/index.ts, src/lib/client.ts, src/lib/constants.ts, src/lib/index.ts, src/react/index.ts, src/react/utils.ts, src/tts/index.ts, src/tts/player.ts, src/tts/source.ts, src/tts/utils.ts, src/tts/websocket.ts, src/types/index.ts, src/voices/index.ts
3
3
  CLI Using tsconfig: tsconfig.json
4
4
  CLI tsup v8.0.2
5
5
  CLI Target: es6
6
6
  CJS Build start
7
7
  ESM Build start
8
+ CJS dist/index.cjs 21.16 KB
9
+ CJS dist/lib/client.cjs 3.51 KB
10
+ CJS dist/react/index.cjs 27.38 KB
11
+ CJS dist/tts/index.cjs 15.80 KB
8
12
  CJS dist/types/index.cjs 764.00 B
9
- CJS dist/index.cjs 13.34 KB
10
- CJS dist/audio/index.cjs 13.05 KB
11
- CJS dist/audio/utils.cjs 5.24 KB
12
- CJS dist/lib/client.cjs 1.40 KB
13
- CJS dist/lib/constants.cjs 1.35 KB
14
- CJS dist/lib/index.cjs 13.32 KB
15
- CJS dist/react/index.cjs 18.78 KB
13
+ CJS dist/voices/index.cjs 5.21 KB
14
+ CJS dist/lib/constants.cjs 1.61 KB
15
+ CJS dist/lib/index.cjs 17.33 KB
16
16
  CJS dist/react/utils.cjs 1.80 KB
17
- CJS ⚡️ Build success in 76ms
18
- ESM dist/index.js 276.00 B
19
- ESM dist/audio/index.js 219.00 B
17
+ CJS dist/tts/player.cjs 6.66 KB
18
+ CJS dist/tts/source.cjs 6.63 KB
19
+ CJS dist/tts/utils.cjs 3.87 KB
20
+ CJS dist/tts/websocket.cjs 15.49 KB
21
+ CJS ⚡️ Build success in 134ms
20
22
  ESM dist/chunk-FXPGR372.js 0 B
23
+ ESM dist/tts/source.js 112.00 B
24
+ ESM dist/tts/utils.js 395.00 B
25
+ ESM dist/tts/websocket.js 242.00 B
26
+ ESM dist/types/index.js 31.00 B
27
+ ESM dist/voices/index.js 174.00 B
28
+ ESM dist/index.js 437.00 B
21
29
  ESM dist/lib/client.js 132.00 B
22
- ESM dist/react/index.js 4.31 KB
23
- ESM dist/audio/utils.js 498.00 B
24
- ESM dist/lib/constants.js 185.00 B
25
- ESM dist/lib/index.js 229.00 B
26
- ESM dist/chunk-S6A27RQL.js 288.00 B
27
- ESM dist/chunk-4MHF74A7.js 7.88 KB
28
- ESM dist/chunk-5TSWLYOW.js 3.22 KB
29
- ESM dist/chunk-MJIFZWHS.js 385.00 B
30
- ESM dist/chunk-OVI3W3GG.js 275.00 B
30
+ ESM dist/lib/constants.js 183.00 B
31
+ ESM dist/lib/index.js 322.00 B
32
+ ESM dist/react/index.js 6.22 KB
33
+ ESM dist/chunk-T3RG6WV4.js 353.00 B
34
+ ESM dist/chunk-WVTITUXX.js 1.35 KB
31
35
  ESM dist/react/utils.js 109.00 B
32
- ESM dist/chunk-XPIMIAAE.js 337.00 B
33
- ESM dist/chunk-R4P7LWVZ.js 1.76 KB
34
- ESM dist/types/index.js 31.00 B
35
- ESM ⚡️ Build success in 78ms
36
+ ESM dist/chunk-3FL2SNIR.js 337.00 B
37
+ ESM dist/tts/index.js 261.00 B
38
+ ESM dist/chunk-KWBSQZTY.js 439.00 B
39
+ ESM dist/chunk-3F5E46FT.js 5.81 KB
40
+ ESM dist/chunk-PQ6CIPFW.js 4.02 KB
41
+ ESM dist/chunk-JGP5BIUV.js 841.00 B
42
+ ESM dist/chunk-XHTDPLFR.js 542.00 B
43
+ ESM dist/tts/player.js 143.00 B
44
+ ESM dist/chunk-36JBKJUN.js 3.52 KB
45
+ ESM dist/chunk-RO7TY474.js 1.95 KB
46
+ ESM dist/chunk-WIFMLPT5.js 2.27 KB
47
+ ESM ⚡️ Build success in 140ms
36
48
  DTS Build start
37
- DTS ⚡️ Build success in 7157ms
38
- DTS dist/lib/constants.d.cts 211.00 B
39
- DTS dist/react/index.d.cts 749.00 B
40
- DTS dist/lib/client.d.cts 181.00 B
41
- DTS dist/react/utils.d.cts 240.00 B
42
- DTS dist/types/index.d.cts 103.00 B
43
- DTS dist/lib/index.d.cts 327.00 B
44
- DTS dist/audio/utils.d.cts 400.00 B
45
- DTS dist/audio/index.d.cts 232.00 B
46
- DTS dist/index.d.cts 215.00 B
47
- DTS dist/index-C2_3XFxn.d.cts 6.59 KB
48
- DTS dist/lib/constants.d.ts 211.00 B
49
- DTS dist/react/index.d.ts 746.00 B
50
- DTS dist/lib/client.d.ts 180.00 B
51
- DTS dist/react/utils.d.ts 240.00 B
52
- DTS dist/types/index.d.ts 103.00 B
53
- DTS dist/lib/index.d.ts 324.00 B
54
- DTS dist/audio/utils.d.ts 397.00 B
55
- DTS dist/audio/index.d.ts 229.00 B
56
- DTS dist/index.d.ts 211.00 B
57
- DTS dist/index-DgwnZezj.d.ts 6.59 KB
49
+ DTS ⚡️ Build success in 8877ms
50
+ DTS dist/index.d.cts 509.00 B
51
+ DTS dist/lib/constants.d.cts 247.00 B
52
+ DTS dist/lib/index.d.cts 410.00 B
53
+ DTS dist/react/index.d.cts 1018.00 B
54
+ DTS dist/react/utils.d.cts 240.00 B
55
+ DTS dist/tts/index.d.cts 471.00 B
56
+ DTS dist/tts/player.d.cts 1.06 KB
57
+ DTS dist/tts/utils.d.cts 2.56 KB
58
+ DTS dist/tts/websocket.d.cts 2.39 KB
59
+ DTS dist/tts/source.d.cts 2.17 KB
60
+ DTS dist/voices/index.d.cts 399.00 B
61
+ DTS dist/lib/client.d.cts 267.00 B
62
+ DTS dist/types/index.d.cts 1.28 KB
63
+ DTS dist/index.d.ts 501.00 B
64
+ DTS dist/lib/constants.d.ts 247.00 B
65
+ DTS dist/lib/index.d.ts 404.00 B
66
+ DTS dist/react/index.d.ts 1016.00 B
67
+ DTS dist/react/utils.d.ts 240.00 B
68
+ DTS dist/tts/index.d.ts 467.00 B
69
+ DTS dist/tts/player.d.ts 1.06 KB
70
+ DTS dist/tts/utils.d.ts 2.55 KB
71
+ DTS dist/tts/websocket.d.ts 2.39 KB
72
+ DTS dist/tts/source.d.ts 2.16 KB
73
+ DTS dist/voices/index.d.ts 397.00 B
74
+ DTS dist/lib/client.d.ts 266.00 B
75
+ DTS dist/types/index.d.ts 1.28 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @cartesia/cartesia-js
2
2
 
3
+ ## 1.0.0-alpha.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 585d2c9: Makes JS client compatible with the Cartesia Stable API (2024-06-10)
8
+
9
+ ## 1.0.0-alpha.1
10
+
11
+ ### Major Changes
12
+
13
+ - 3ee5bfc: Initial release of Cartesia client with voices and WebSocket support
14
+
3
15
  ## 0.0.4-alpha.0
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -15,39 +15,146 @@ bun add @cartesia/cartesia-js
15
15
 
16
16
  ## Usage
17
17
 
18
- ```javascript
18
+ ### CRUD on Voices
19
+
20
+ ```js
21
+ import Cartesia from "@cartesia/cartesia-js";
22
+
23
+ const cartesia = new Cartesia({
24
+ apiKey: "your-api-key",
25
+ });
26
+
27
+ // List all voices.
28
+ const voices = await cartesia.voices.list();
29
+ console.log(voices);
30
+
31
+ // Get a voice.
32
+ const voice = await cartesia.voices.get("<voice-id>");
33
+ console.log(voice);
34
+
35
+ // Create a voice.
36
+ const newVoice = await cartesia.voices.create({
37
+ name: "Tim",
38
+ description: "A deep, resonant voice.",
39
+ embedding: Array(192).fill(1.0),
40
+ });
41
+ console.log(newVoice);
42
+
43
+ // Clone a voice from a URL.
44
+ const clonedVoice = await cartesia.voices.clone({
45
+ mode: "url",
46
+ url: "https://youtu.be/AdtLxlttrHg?si=07OLmDPg__0IN14f&t=6",
47
+ });
48
+
49
+ // Clone a voice from a file.
50
+ const clonedVoice = await cartesia.voices.clone({
51
+ mode: "clip",
52
+ clip: myFile, // Pass a File object or a Blob.
53
+ });
54
+ ```
55
+
56
+ ### TTS over WebSocket
57
+
58
+ ```js
19
59
  import Cartesia from "@cartesia/cartesia-js";
20
60
 
21
- const cartesia = new Cartesia();
61
+ const cartesia = new Cartesia({
62
+ apiKey: "your-api-key",
63
+ });
64
+
65
+ // Initialize the WebSocket. Make sure the sample rate you specify is supported.
66
+ const websocket = cartesia.tts.websocket({ sampleRate: 44100 });
22
67
 
23
68
  try {
24
- await cartesia.audio.connect();
69
+ await websocket.connect();
25
70
  } catch (error) {
26
71
  console.error(`Failed to connect to Cartesia: ${error}`);
27
72
  }
28
73
 
29
- const stream = await cartesia.audio.stream({
74
+ // Create a stream.
75
+ const response = await websocket.send({
30
76
  model: "upbeat-moon",
31
- options: {
32
- transcript: "Hello, world!",
33
- chunk_time: 0.1,
77
+ voice: {
78
+ mode: "embedding",
79
+ embedding: Array(192).fill(1.0),
34
80
  },
81
+ transcript: "Hello, world!"
82
+ // The WebSocket sets output_format on your behalf.
83
+ // The container is "raw" and the encoding is "pcm_f32le".
35
84
  });
36
85
 
37
- console.log(`Created stream ${stream.id}.`);
38
-
39
- stream.on("chunk", ({ chunk, chunks }) => {
40
- console.log("Received chunk:", chunk);
41
- console.log("All chunks:", chunks);
86
+ // Access the raw messages from the WebSocket.
87
+ response.on("message", (message) => {
88
+ // Raw message.
89
+ console.log("Received message:", message);
42
90
  });
43
91
 
44
- stream.on("message", ({ message }) => {
92
+ // You can also access messages using a for-await-of loop.
93
+ for await (const message of response.events('message')) {
45
94
  // Raw message.
46
95
  console.log("Received message:", message);
47
- });
96
+ }
97
+ ```
98
+
99
+ #### Playing audio in the browser
100
+
101
+ (We currently only support playing audio in the browser. Support for other JS environments is coming soon.)
102
+
103
+ ```js
104
+ // If you're using the client in the browser, you can play the audio like this:
105
+ import { WebPlayer } from "@cartesia/cartesia-js";
48
106
 
49
- // If you're using the client in the browser, you can play the stream like this:
50
107
  console.log("Playing stream...");
51
- await stream.play();
108
+
109
+ // Create a Player object.
110
+ const player = new WebPlayer();
111
+
112
+ // Play the audio. (`response` includes a custom Source object that the Player can play.)
113
+ // The call resolves when the audio finishes playing.
114
+ await player.play(response.source);
115
+
52
116
  console.log("Done playing.");
53
117
  ```
118
+
119
+ ## React
120
+
121
+ We export a React hook that simplifies the process of using the TTS API. The hook manages the WebSocket connection and provides a simple interface for buffering and playing audio.
122
+
123
+ ```jsx
124
+ import { useTTS } from '@cartesia/cartesia-js/react';
125
+
126
+ function TextToSpeech() {
127
+ const tts = useTTS({
128
+ apiKey: "your-api-key",
129
+ samplingRate: 44100,
130
+ })
131
+
132
+ const [text, setText] = useState("");
133
+
134
+ const handlePlay = async () => {
135
+ // Begin buffering the audio.
136
+ const response = await tts.buffer({
137
+ model: "upbeat-moon",
138
+ voice: {
139
+ mode: "embedding",
140
+ embedding: Array(192).fill(1.0),
141
+ },
142
+ transcript: text,
143
+ });
144
+
145
+ // Immediately play the audio. (You can also buffer in advance and play later.)
146
+ await tts.play();
147
+ }
148
+
149
+ return (
150
+ <div>
151
+ <input type="text" value={text} onChange={(event) => setText(event.target.value)} />
152
+ <button onClick={handlePlay}>Play</button>
153
+
154
+ <div>
155
+ {tts.playbackStatus} | {tts.bufferStatus} | {tts.isWaiting}
156
+ </div>
157
+ </div>
158
+ );
159
+ }
160
+ ```
@@ -0,0 +1,119 @@
1
+ import {
2
+ playAudioBuffer
3
+ } from "./chunk-RO7TY474.js";
4
+ import {
5
+ __async,
6
+ __privateAdd,
7
+ __privateGet,
8
+ __privateMethod,
9
+ __privateSet
10
+ } from "./chunk-WIFMLPT5.js";
11
+
12
+ // src/tts/player.ts
13
+ import Emittery from "emittery";
14
+ var _context, _startNextPlaybackAt, _bufferDuration, _emitter, _playBuffer, playBuffer_fn;
15
+ var Player = class {
16
+ /**
17
+ * Create a new Player.
18
+ *
19
+ * @param options - Options for the Player.
20
+ * @param options.bufferDuration - The duration of the audio buffer to play.
21
+ */
22
+ constructor({ bufferDuration }) {
23
+ __privateAdd(this, _playBuffer);
24
+ __privateAdd(this, _context, null);
25
+ __privateAdd(this, _startNextPlaybackAt, 0);
26
+ __privateAdd(this, _bufferDuration, void 0);
27
+ __privateAdd(this, _emitter, new Emittery());
28
+ __privateSet(this, _bufferDuration, bufferDuration);
29
+ }
30
+ /**
31
+ * Play audio from a source.
32
+ *
33
+ * @param source The source to play audio from.
34
+ * @returns A promise that resolves when the audio has finished playing.
35
+ */
36
+ play(source) {
37
+ return __async(this, null, function* () {
38
+ __privateSet(this, _startNextPlaybackAt, 0);
39
+ __privateSet(this, _context, new AudioContext({ sampleRate: source.sampleRate }));
40
+ const buffer = new Float32Array(
41
+ source.durationToSampleCount(__privateGet(this, _bufferDuration))
42
+ );
43
+ const plays = [];
44
+ while (true) {
45
+ const read = yield source.read(buffer);
46
+ const playableAudio = buffer.subarray(0, read);
47
+ plays.push(__privateMethod(this, _playBuffer, playBuffer_fn).call(this, playableAudio, source.sampleRate));
48
+ if (read < buffer.length) {
49
+ yield __privateGet(this, _emitter).emit("finish");
50
+ break;
51
+ }
52
+ }
53
+ yield Promise.all(plays);
54
+ });
55
+ }
56
+ /**
57
+ * Pause the audio.
58
+ *
59
+ * @returns A promise that resolves when the audio has been paused.
60
+ */
61
+ pause() {
62
+ return __async(this, null, function* () {
63
+ if (!__privateGet(this, _context)) {
64
+ throw new Error("AudioContext not initialized.");
65
+ }
66
+ yield __privateGet(this, _context).suspend();
67
+ });
68
+ }
69
+ /**
70
+ * Resume the audio.
71
+ *
72
+ * @returns A promise that resolves when the audio has been resumed.
73
+ */
74
+ resume() {
75
+ return __async(this, null, function* () {
76
+ if (!__privateGet(this, _context)) {
77
+ throw new Error("AudioContext not initialized.");
78
+ }
79
+ yield __privateGet(this, _context).resume();
80
+ });
81
+ }
82
+ /**
83
+ * Toggle the audio.
84
+ *
85
+ * @returns A promise that resolves when the audio has been toggled.
86
+ */
87
+ toggle() {
88
+ return __async(this, null, function* () {
89
+ if (!__privateGet(this, _context)) {
90
+ throw new Error("AudioContext not initialized.");
91
+ }
92
+ if (__privateGet(this, _context).state === "running") {
93
+ yield this.pause();
94
+ } else {
95
+ yield this.resume();
96
+ }
97
+ });
98
+ }
99
+ };
100
+ _context = new WeakMap();
101
+ _startNextPlaybackAt = new WeakMap();
102
+ _bufferDuration = new WeakMap();
103
+ _emitter = new WeakMap();
104
+ _playBuffer = new WeakSet();
105
+ playBuffer_fn = function(buf, sampleRate) {
106
+ return __async(this, null, function* () {
107
+ if (!__privateGet(this, _context)) {
108
+ throw new Error("AudioContext not initialized.");
109
+ }
110
+ const startAt = __privateGet(this, _startNextPlaybackAt);
111
+ const duration = buf.length / sampleRate;
112
+ __privateSet(this, _startNextPlaybackAt, duration + Math.max(__privateGet(this, _context).currentTime, __privateGet(this, _startNextPlaybackAt)));
113
+ yield playAudioBuffer(buf, __privateGet(this, _context), startAt, sampleRate);
114
+ });
115
+ };
116
+
117
+ export {
118
+ Player
119
+ };
@@ -0,0 +1,212 @@
1
+ import {
2
+ Source
3
+ } from "./chunk-PQ6CIPFW.js";
4
+ import {
5
+ Client
6
+ } from "./chunk-JGP5BIUV.js";
7
+ import {
8
+ CARTESIA_VERSION,
9
+ constructApiUrl
10
+ } from "./chunk-XHTDPLFR.js";
11
+ import {
12
+ base64ToArray,
13
+ createMessageHandlerForContextId,
14
+ getEmitteryCallbacks,
15
+ isSentinel
16
+ } from "./chunk-RO7TY474.js";
17
+ import {
18
+ __async,
19
+ __privateAdd,
20
+ __privateGet,
21
+ __privateMethod,
22
+ __privateSet,
23
+ __spreadProps,
24
+ __spreadValues
25
+ } from "./chunk-WIFMLPT5.js";
26
+
27
+ // src/tts/websocket.ts
28
+ import Emittery from "emittery";
29
+ import { humanId } from "human-id";
30
+ import { WebSocket as PartySocketWebSocket } from "partysocket";
31
+ var _isConnected, _sampleRate, _generateId, generateId_fn;
32
+ var WebSocket = class extends Client {
33
+ /**
34
+ * Create a new WebSocket client.
35
+ *
36
+ * @param args - Arguments to pass to the Client constructor.
37
+ */
38
+ constructor({ sampleRate }, ...args) {
39
+ super(...args);
40
+ /**
41
+ * Generate a unique ID suitable for a streaming context.
42
+ *
43
+ * Not suitable for security purposes or as a primary key, since
44
+ * it lacks the amount of entropy required for those use cases.
45
+ *
46
+ * @returns A unique ID.
47
+ */
48
+ __privateAdd(this, _generateId);
49
+ __privateAdd(this, _isConnected, false);
50
+ __privateAdd(this, _sampleRate, void 0);
51
+ __privateSet(this, _sampleRate, sampleRate);
52
+ }
53
+ /**
54
+ * Send a message over the WebSocket in order to start a stream.
55
+ *
56
+ * @param inputs - Stream options.
57
+ * @param options - Options for the stream.
58
+ * @param options.timeout - The maximum time to wait for a chunk before cancelling the stream.
59
+ * If `0`, the stream will not time out.
60
+ * @returns A Source object that can be passed to a Player to play the audio.
61
+ */
62
+ send(inputs, { timeout = 0 } = {}) {
63
+ var _a, _b, _c, _d;
64
+ if (!__privateGet(this, _isConnected)) {
65
+ throw new Error("Not connected to WebSocket. Call .connect() first.");
66
+ }
67
+ const contextId = __privateMethod(this, _generateId, generateId_fn).call(this);
68
+ (_a = this.socket) == null ? void 0 : _a.send(
69
+ JSON.stringify(__spreadProps(__spreadValues({
70
+ context_id: contextId
71
+ }, inputs), {
72
+ output_format: {
73
+ container: "raw",
74
+ encoding: "pcm_f32le",
75
+ sample_rate: __privateGet(this, _sampleRate)
76
+ }
77
+ }))
78
+ );
79
+ const emitter = new Emittery();
80
+ const source = new Source({
81
+ sampleRate: __privateGet(this, _sampleRate)
82
+ });
83
+ const streamCompleteController = new AbortController();
84
+ let timeoutId = null;
85
+ if (timeout > 0) {
86
+ timeoutId = setTimeout(streamCompleteController.abort, timeout);
87
+ }
88
+ const handleMessage = createMessageHandlerForContextId(
89
+ contextId,
90
+ (_0) => __async(this, [_0], function* ({ chunk, message }) {
91
+ emitter.emit("message", message);
92
+ if (isSentinel(chunk)) {
93
+ yield source.close();
94
+ streamCompleteController.abort();
95
+ return;
96
+ }
97
+ yield source.enqueue(base64ToArray([chunk]));
98
+ if (timeoutId) {
99
+ clearTimeout(timeoutId);
100
+ timeoutId = setTimeout(streamCompleteController.abort, timeout);
101
+ }
102
+ })
103
+ );
104
+ (_b = this.socket) == null ? void 0 : _b.addEventListener("message", handleMessage, {
105
+ signal: streamCompleteController.signal
106
+ });
107
+ (_c = this.socket) == null ? void 0 : _c.addEventListener(
108
+ "close",
109
+ () => {
110
+ streamCompleteController.abort();
111
+ },
112
+ {
113
+ once: true
114
+ }
115
+ );
116
+ (_d = this.socket) == null ? void 0 : _d.addEventListener(
117
+ "error",
118
+ () => {
119
+ streamCompleteController.abort();
120
+ },
121
+ {
122
+ once: true
123
+ }
124
+ );
125
+ streamCompleteController.signal.addEventListener("abort", () => {
126
+ source.close();
127
+ if (timeoutId) {
128
+ clearTimeout(timeoutId);
129
+ }
130
+ });
131
+ return __spreadValues({ source }, getEmitteryCallbacks(emitter));
132
+ }
133
+ /**
134
+ * Authenticate and connect to a Cartesia streaming WebSocket.
135
+ *
136
+ * @returns A promise that resolves when the WebSocket is connected.
137
+ * @throws {Error} If the WebSocket fails to connect.
138
+ */
139
+ connect() {
140
+ const url = constructApiUrl(
141
+ this.baseUrl,
142
+ `/tts/websocket?cartesia_version=${CARTESIA_VERSION}`,
143
+ "ws"
144
+ );
145
+ url.searchParams.set("api_key", this.apiKey);
146
+ const emitter = new Emittery();
147
+ this.socket = new PartySocketWebSocket(url.toString());
148
+ this.socket.onopen = () => {
149
+ __privateSet(this, _isConnected, true);
150
+ emitter.emit("open");
151
+ };
152
+ this.socket.onclose = () => {
153
+ __privateSet(this, _isConnected, false);
154
+ emitter.emit("close");
155
+ };
156
+ return new Promise(
157
+ (resolve, reject) => {
158
+ var _a, _b, _c;
159
+ (_a = this.socket) == null ? void 0 : _a.addEventListener(
160
+ "open",
161
+ () => {
162
+ resolve(getEmitteryCallbacks(emitter));
163
+ },
164
+ {
165
+ once: true
166
+ }
167
+ );
168
+ const aborter = new AbortController();
169
+ (_b = this.socket) == null ? void 0 : _b.addEventListener(
170
+ "error",
171
+ () => {
172
+ aborter.abort();
173
+ reject(new Error("WebSocket failed to connect."));
174
+ },
175
+ {
176
+ signal: aborter.signal
177
+ }
178
+ );
179
+ (_c = this.socket) == null ? void 0 : _c.addEventListener(
180
+ "close",
181
+ () => {
182
+ aborter.abort();
183
+ reject(new Error("WebSocket closed before it could connect."));
184
+ },
185
+ {
186
+ signal: aborter.signal
187
+ }
188
+ );
189
+ }
190
+ );
191
+ }
192
+ /**
193
+ * Disconnect from the Cartesia streaming WebSocket.
194
+ */
195
+ disconnect() {
196
+ var _a;
197
+ (_a = this.socket) == null ? void 0 : _a.close();
198
+ }
199
+ };
200
+ _isConnected = new WeakMap();
201
+ _sampleRate = new WeakMap();
202
+ _generateId = new WeakSet();
203
+ generateId_fn = function() {
204
+ return humanId({
205
+ separator: "-",
206
+ capitalize: false
207
+ });
208
+ };
209
+
210
+ export {
211
+ WebSocket
212
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  __async
3
- } from "./chunk-R4P7LWVZ.js";
3
+ } from "./chunk-WIFMLPT5.js";
4
4
 
5
5
  // src/react/utils.ts
6
6
  function pingServer(url) {
@@ -0,0 +1,34 @@
1
+ import {
2
+ BASE_URL,
3
+ CARTESIA_VERSION,
4
+ constructApiUrl
5
+ } from "./chunk-XHTDPLFR.js";
6
+ import {
7
+ __spreadProps,
8
+ __spreadValues
9
+ } from "./chunk-WIFMLPT5.js";
10
+
11
+ // src/lib/client.ts
12
+ import fetch from "cross-fetch";
13
+ var Client = class {
14
+ constructor(options = {}) {
15
+ if (!(options.apiKey || process.env.CARTESIA_API_KEY)) {
16
+ throw new Error("Missing Cartesia API key.");
17
+ }
18
+ this.apiKey = options.apiKey || process.env.CARTESIA_API_KEY;
19
+ this.baseUrl = options.baseUrl || BASE_URL;
20
+ }
21
+ fetch(path, options = {}) {
22
+ const url = constructApiUrl(this.baseUrl, path);
23
+ return fetch(url.toString(), __spreadProps(__spreadValues({}, options), {
24
+ headers: __spreadValues({
25
+ "X-API-Key": this.apiKey,
26
+ "Cartesia-Version": CARTESIA_VERSION
27
+ }, options.headers)
28
+ }));
29
+ }
30
+ };
31
+
32
+ export {
33
+ Client
34
+ };