@cartesia/cartesia-js 0.0.1 → 0.0.3
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/.turbo/turbo-build.log +45 -47
- package/CHANGELOG.md +12 -0
- package/README.md +17 -2
- package/dist/audio/index.d.mts +2 -1
- package/dist/audio/index.d.ts +2 -1
- package/dist/audio/index.js +90 -48
- package/dist/audio/index.mjs +4 -4
- package/dist/audio/utils.d.mts +2 -1
- package/dist/audio/utils.d.ts +2 -1
- package/dist/audio/utils.js +44 -0
- package/dist/audio/utils.mjs +6 -2
- package/dist/{chunk-5RMUZJV7.mjs → chunk-3CYTAFLF.mjs} +72 -50
- package/dist/{chunk-BTFHUVNH.mjs → chunk-FRIBQZPN.mjs} +44 -2
- package/dist/{chunk-35HX6ML3.mjs → chunk-HNLIBHEN.mjs} +18 -1
- package/dist/{chunk-ERFCRIWU.mjs → chunk-XSFPHPPG.mjs} +1 -1
- package/dist/{index-Dt9A_pEb.d.mts → index-DSBmfK9-.d.mts} +39 -8
- package/dist/{index-Ds4LDkmk.d.ts → index-qwAyxV5I.d.ts} +39 -8
- package/dist/lib/client.mjs +2 -2
- package/dist/lib/constants.js +1 -1
- package/dist/lib/constants.mjs +1 -1
- package/dist/lib/index.d.mts +2 -1
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/index.js +90 -48
- package/dist/lib/index.mjs +4 -4
- package/dist/react/index.d.mts +9 -5
- package/dist/react/index.d.ts +9 -5
- package/dist/react/index.js +178 -60
- package/dist/react/index.mjs +64 -16
- package/package.json +5 -4
- package/src/audio/index.ts +86 -46
- package/src/audio/utils.ts +82 -0
- package/src/lib/constants.ts +1 -1
- package/src/react/index.ts +61 -12
package/dist/lib/index.js
CHANGED
|
@@ -3,11 +3,25 @@ var __create = Object.create;
|
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
8
10
|
var __knownSymbol = (name, symbol) => {
|
|
9
11
|
return (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
10
12
|
};
|
|
13
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
14
|
+
var __spreadValues = (a, b) => {
|
|
15
|
+
for (var prop in b || (b = {}))
|
|
16
|
+
if (__hasOwnProp.call(b, prop))
|
|
17
|
+
__defNormalProp(a, prop, b[prop]);
|
|
18
|
+
if (__getOwnPropSymbols)
|
|
19
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
20
|
+
if (__propIsEnum.call(b, prop))
|
|
21
|
+
__defNormalProp(a, prop, b[prop]);
|
|
22
|
+
}
|
|
23
|
+
return a;
|
|
24
|
+
};
|
|
11
25
|
var __export = (target, all) => {
|
|
12
26
|
for (var name in all)
|
|
13
27
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -61,12 +75,13 @@ module.exports = __toCommonJS(lib_exports);
|
|
|
61
75
|
// src/audio/index.ts
|
|
62
76
|
var import_emittery = __toESM(require("emittery"));
|
|
63
77
|
var import_human_id = require("human-id");
|
|
78
|
+
var import_partysocket = require("partysocket");
|
|
64
79
|
|
|
65
80
|
// src/lib/constants.ts
|
|
66
81
|
var BASE_URL = "https://api.cartesia.ai/v0";
|
|
67
82
|
var SAMPLE_RATE = 44100;
|
|
68
83
|
var constructWebsocketUrl = (baseUrl) => {
|
|
69
|
-
return new URL(`${baseUrl.replace(/^http/, "ws")}/
|
|
84
|
+
return new URL(`${baseUrl.replace(/^http/, "ws")}/audio/websocket`);
|
|
70
85
|
};
|
|
71
86
|
|
|
72
87
|
// src/lib/client.ts
|
|
@@ -136,6 +151,14 @@ function filterSentinel(collection) {
|
|
|
136
151
|
function isComplete(chunks) {
|
|
137
152
|
return isSentinel(chunks[chunks.length - 1]);
|
|
138
153
|
}
|
|
154
|
+
function getEmitteryCallbacks(emitter) {
|
|
155
|
+
return {
|
|
156
|
+
on: emitter.on.bind(emitter),
|
|
157
|
+
off: emitter.off.bind(emitter),
|
|
158
|
+
once: emitter.once.bind(emitter),
|
|
159
|
+
events: emitter.events.bind(emitter)
|
|
160
|
+
};
|
|
161
|
+
}
|
|
139
162
|
|
|
140
163
|
// src/audio/index.ts
|
|
141
164
|
var audio_default = class extends Client {
|
|
@@ -184,6 +207,9 @@ var audio_default = class extends Client {
|
|
|
184
207
|
});
|
|
185
208
|
yield emitter.emit("message", message);
|
|
186
209
|
if (isSentinel(chunk)) {
|
|
210
|
+
yield emitter.emit("streamed", {
|
|
211
|
+
chunks
|
|
212
|
+
});
|
|
187
213
|
streamCompleteController.abort();
|
|
188
214
|
} else if (timeoutId) {
|
|
189
215
|
clearTimeout(timeoutId);
|
|
@@ -194,13 +220,28 @@ var audio_default = class extends Client {
|
|
|
194
220
|
(_b = this.socket) == null ? void 0 : _b.addEventListener("message", handleMessage, {
|
|
195
221
|
signal: streamCompleteController.signal
|
|
196
222
|
});
|
|
197
|
-
(_c = this.socket) == null ? void 0 : _c.addEventListener(
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
223
|
+
(_c = this.socket) == null ? void 0 : _c.addEventListener(
|
|
224
|
+
"close",
|
|
225
|
+
() => {
|
|
226
|
+
streamCompleteController.abort();
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
once: true
|
|
230
|
+
}
|
|
231
|
+
);
|
|
232
|
+
(_d = this.socket) == null ? void 0 : _d.addEventListener(
|
|
233
|
+
"error",
|
|
234
|
+
() => {
|
|
235
|
+
streamCompleteController.abort();
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
once: true
|
|
239
|
+
}
|
|
240
|
+
);
|
|
203
241
|
streamCompleteController.signal.addEventListener("abort", () => {
|
|
242
|
+
if (timeoutId) {
|
|
243
|
+
clearTimeout(timeoutId);
|
|
244
|
+
}
|
|
204
245
|
emitter.clearListeners();
|
|
205
246
|
});
|
|
206
247
|
const play = (_0) => __async(this, [_0], function* ({ bufferDuration }) {
|
|
@@ -274,13 +315,9 @@ var audio_default = class extends Client {
|
|
|
274
315
|
}
|
|
275
316
|
}
|
|
276
317
|
});
|
|
277
|
-
return {
|
|
278
|
-
play
|
|
279
|
-
|
|
280
|
-
off: emitter.off.bind(emitter),
|
|
281
|
-
once: emitter.once.bind(emitter),
|
|
282
|
-
events: emitter.events.bind(emitter)
|
|
283
|
-
};
|
|
318
|
+
return __spreadValues({
|
|
319
|
+
play
|
|
320
|
+
}, getEmitteryCallbacks(emitter));
|
|
284
321
|
}
|
|
285
322
|
/**
|
|
286
323
|
* Generate a unique ID suitable for a streaming context.
|
|
@@ -305,46 +342,51 @@ var audio_default = class extends Client {
|
|
|
305
342
|
connect() {
|
|
306
343
|
const url = constructWebsocketUrl(this.baseUrl);
|
|
307
344
|
url.searchParams.set("api_key", this.apiKey);
|
|
308
|
-
|
|
345
|
+
const emitter = new import_emittery.default();
|
|
346
|
+
this.socket = new import_partysocket.WebSocket(url.toString());
|
|
309
347
|
this.socket.onopen = () => {
|
|
310
348
|
this.isConnected = true;
|
|
349
|
+
emitter.emit("open");
|
|
311
350
|
};
|
|
312
351
|
this.socket.onclose = () => {
|
|
313
352
|
this.isConnected = false;
|
|
353
|
+
emitter.emit("close");
|
|
314
354
|
};
|
|
315
|
-
return new Promise(
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
355
|
+
return new Promise(
|
|
356
|
+
(resolve, reject) => {
|
|
357
|
+
var _a, _b, _c;
|
|
358
|
+
(_a = this.socket) == null ? void 0 : _a.addEventListener(
|
|
359
|
+
"open",
|
|
360
|
+
() => {
|
|
361
|
+
resolve(getEmitteryCallbacks(emitter));
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
once: true
|
|
365
|
+
}
|
|
366
|
+
);
|
|
367
|
+
const aborter = new AbortController();
|
|
368
|
+
(_b = this.socket) == null ? void 0 : _b.addEventListener(
|
|
369
|
+
"error",
|
|
370
|
+
() => {
|
|
371
|
+
aborter.abort();
|
|
372
|
+
reject(new Error("WebSocket failed to connect."));
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
signal: aborter.signal
|
|
376
|
+
}
|
|
377
|
+
);
|
|
378
|
+
(_c = this.socket) == null ? void 0 : _c.addEventListener(
|
|
379
|
+
"close",
|
|
380
|
+
() => {
|
|
381
|
+
aborter.abort();
|
|
382
|
+
reject(new Error("WebSocket closed before it could connect."));
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
signal: aborter.signal
|
|
386
|
+
}
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
);
|
|
348
390
|
}
|
|
349
391
|
/**
|
|
350
392
|
* Disconnect from the Cartesia streaming WebSocket.
|
package/dist/lib/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
audio_default
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-3CYTAFLF.mjs";
|
|
4
|
+
import "../chunk-FRIBQZPN.mjs";
|
|
5
5
|
import {
|
|
6
6
|
Client
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
} from "../chunk-XSFPHPPG.mjs";
|
|
8
|
+
import "../chunk-HNLIBHEN.mjs";
|
|
9
9
|
|
|
10
10
|
// src/lib/index.ts
|
|
11
11
|
var Cartesia = class extends Client {
|
package/dist/react/index.d.mts
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
import { C as Chunk, S as StreamEventData } from '../index-
|
|
1
|
+
import { C as Chunk, S as StreamEventData } from '../index-DSBmfK9-.mjs';
|
|
2
2
|
import 'emittery';
|
|
3
|
+
import 'partysocket';
|
|
3
4
|
import '../lib/client.mjs';
|
|
4
5
|
import '../types/index.mjs';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
apiKey: string;
|
|
7
|
+
type UseAudioOptions = {
|
|
8
|
+
apiKey: string | null;
|
|
8
9
|
baseUrl?: string;
|
|
9
|
-
}
|
|
10
|
+
};
|
|
10
11
|
interface UseAudioReturn {
|
|
11
12
|
stream: (options: object) => void;
|
|
12
13
|
play: (bufferDuration?: number) => Promise<void>;
|
|
14
|
+
download: () => Blob | null;
|
|
13
15
|
isPlaying: boolean;
|
|
16
|
+
isConnected: boolean;
|
|
17
|
+
isStreamed: boolean;
|
|
14
18
|
chunks: Chunk[];
|
|
15
19
|
messages: StreamEventData["message"][];
|
|
16
20
|
}
|
|
@@ -19,4 +23,4 @@ interface UseAudioReturn {
|
|
|
19
23
|
*/
|
|
20
24
|
declare function useAudio({ apiKey, baseUrl }: UseAudioOptions): UseAudioReturn;
|
|
21
25
|
|
|
22
|
-
export { useAudio };
|
|
26
|
+
export { type UseAudioOptions, useAudio };
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
import { C as Chunk, S as StreamEventData } from '../index-
|
|
1
|
+
import { C as Chunk, S as StreamEventData } from '../index-qwAyxV5I.js';
|
|
2
2
|
import 'emittery';
|
|
3
|
+
import 'partysocket';
|
|
3
4
|
import '../lib/client.js';
|
|
4
5
|
import '../types/index.js';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
apiKey: string;
|
|
7
|
+
type UseAudioOptions = {
|
|
8
|
+
apiKey: string | null;
|
|
8
9
|
baseUrl?: string;
|
|
9
|
-
}
|
|
10
|
+
};
|
|
10
11
|
interface UseAudioReturn {
|
|
11
12
|
stream: (options: object) => void;
|
|
12
13
|
play: (bufferDuration?: number) => Promise<void>;
|
|
14
|
+
download: () => Blob | null;
|
|
13
15
|
isPlaying: boolean;
|
|
16
|
+
isConnected: boolean;
|
|
17
|
+
isStreamed: boolean;
|
|
14
18
|
chunks: Chunk[];
|
|
15
19
|
messages: StreamEventData["message"][];
|
|
16
20
|
}
|
|
@@ -19,4 +23,4 @@ interface UseAudioReturn {
|
|
|
19
23
|
*/
|
|
20
24
|
declare function useAudio({ apiKey, baseUrl }: UseAudioOptions): UseAudioReturn;
|
|
21
25
|
|
|
22
|
-
export { useAudio };
|
|
26
|
+
export { type UseAudioOptions, useAudio };
|
package/dist/react/index.js
CHANGED
|
@@ -3,11 +3,25 @@ var __create = Object.create;
|
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
8
10
|
var __knownSymbol = (name, symbol) => {
|
|
9
11
|
return (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
10
12
|
};
|
|
13
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
14
|
+
var __spreadValues = (a, b) => {
|
|
15
|
+
for (var prop in b || (b = {}))
|
|
16
|
+
if (__hasOwnProp.call(b, prop))
|
|
17
|
+
__defNormalProp(a, prop, b[prop]);
|
|
18
|
+
if (__getOwnPropSymbols)
|
|
19
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
20
|
+
if (__propIsEnum.call(b, prop))
|
|
21
|
+
__defNormalProp(a, prop, b[prop]);
|
|
22
|
+
}
|
|
23
|
+
return a;
|
|
24
|
+
};
|
|
11
25
|
var __export = (target, all) => {
|
|
12
26
|
for (var name in all)
|
|
13
27
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -62,12 +76,13 @@ var import_react = require("react");
|
|
|
62
76
|
// src/audio/index.ts
|
|
63
77
|
var import_emittery = __toESM(require("emittery"));
|
|
64
78
|
var import_human_id = require("human-id");
|
|
79
|
+
var import_partysocket = require("partysocket");
|
|
65
80
|
|
|
66
81
|
// src/lib/constants.ts
|
|
67
82
|
var BASE_URL = "https://api.cartesia.ai/v0";
|
|
68
83
|
var SAMPLE_RATE = 44100;
|
|
69
84
|
var constructWebsocketUrl = (baseUrl) => {
|
|
70
|
-
return new URL(`${baseUrl.replace(/^http/, "ws")}/
|
|
85
|
+
return new URL(`${baseUrl.replace(/^http/, "ws")}/audio/websocket`);
|
|
71
86
|
};
|
|
72
87
|
|
|
73
88
|
// src/lib/client.ts
|
|
@@ -137,6 +152,46 @@ function filterSentinel(collection) {
|
|
|
137
152
|
function isComplete(chunks) {
|
|
138
153
|
return isSentinel(chunks[chunks.length - 1]);
|
|
139
154
|
}
|
|
155
|
+
function getEmitteryCallbacks(emitter) {
|
|
156
|
+
return {
|
|
157
|
+
on: emitter.on.bind(emitter),
|
|
158
|
+
off: emitter.off.bind(emitter),
|
|
159
|
+
once: emitter.once.bind(emitter),
|
|
160
|
+
events: emitter.events.bind(emitter)
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function bufferToWav(sampleRate, channelBuffers) {
|
|
164
|
+
const totalSamples = channelBuffers[0].length * channelBuffers.length;
|
|
165
|
+
const buffer = new ArrayBuffer(44 + totalSamples * 2);
|
|
166
|
+
const view = new DataView(buffer);
|
|
167
|
+
const writeString = (view2, offset2, string) => {
|
|
168
|
+
for (let i = 0; i < string.length; i++) {
|
|
169
|
+
view2.setUint8(offset2 + i, string.charCodeAt(i));
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
writeString(view, 0, "RIFF");
|
|
173
|
+
view.setUint32(4, 36 + totalSamples * 2, true);
|
|
174
|
+
writeString(view, 8, "WAVE");
|
|
175
|
+
writeString(view, 12, "fmt ");
|
|
176
|
+
view.setUint32(16, 16, true);
|
|
177
|
+
view.setUint16(20, 1, true);
|
|
178
|
+
view.setUint16(22, channelBuffers.length, true);
|
|
179
|
+
view.setUint32(24, sampleRate, true);
|
|
180
|
+
view.setUint32(28, sampleRate * 4, true);
|
|
181
|
+
view.setUint16(32, channelBuffers.length * 2, true);
|
|
182
|
+
view.setUint16(34, 16, true);
|
|
183
|
+
writeString(view, 36, "data");
|
|
184
|
+
view.setUint32(40, totalSamples * 2, true);
|
|
185
|
+
let offset = 44;
|
|
186
|
+
for (let i = 0; i < channelBuffers[0].length; i++) {
|
|
187
|
+
for (let channel = 0; channel < channelBuffers.length; channel++) {
|
|
188
|
+
const s = Math.max(-1, Math.min(1, channelBuffers[channel][i]));
|
|
189
|
+
view.setInt16(offset, s < 0 ? s * 32768 : s * 32767, true);
|
|
190
|
+
offset += 2;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return buffer;
|
|
194
|
+
}
|
|
140
195
|
|
|
141
196
|
// src/audio/index.ts
|
|
142
197
|
var audio_default = class extends Client {
|
|
@@ -185,6 +240,9 @@ var audio_default = class extends Client {
|
|
|
185
240
|
});
|
|
186
241
|
yield emitter.emit("message", message);
|
|
187
242
|
if (isSentinel(chunk)) {
|
|
243
|
+
yield emitter.emit("streamed", {
|
|
244
|
+
chunks
|
|
245
|
+
});
|
|
188
246
|
streamCompleteController.abort();
|
|
189
247
|
} else if (timeoutId) {
|
|
190
248
|
clearTimeout(timeoutId);
|
|
@@ -195,13 +253,28 @@ var audio_default = class extends Client {
|
|
|
195
253
|
(_b = this.socket) == null ? void 0 : _b.addEventListener("message", handleMessage, {
|
|
196
254
|
signal: streamCompleteController.signal
|
|
197
255
|
});
|
|
198
|
-
(_c = this.socket) == null ? void 0 : _c.addEventListener(
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
256
|
+
(_c = this.socket) == null ? void 0 : _c.addEventListener(
|
|
257
|
+
"close",
|
|
258
|
+
() => {
|
|
259
|
+
streamCompleteController.abort();
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
once: true
|
|
263
|
+
}
|
|
264
|
+
);
|
|
265
|
+
(_d = this.socket) == null ? void 0 : _d.addEventListener(
|
|
266
|
+
"error",
|
|
267
|
+
() => {
|
|
268
|
+
streamCompleteController.abort();
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
once: true
|
|
272
|
+
}
|
|
273
|
+
);
|
|
204
274
|
streamCompleteController.signal.addEventListener("abort", () => {
|
|
275
|
+
if (timeoutId) {
|
|
276
|
+
clearTimeout(timeoutId);
|
|
277
|
+
}
|
|
205
278
|
emitter.clearListeners();
|
|
206
279
|
});
|
|
207
280
|
const play = (_0) => __async(this, [_0], function* ({ bufferDuration }) {
|
|
@@ -275,13 +348,9 @@ var audio_default = class extends Client {
|
|
|
275
348
|
}
|
|
276
349
|
}
|
|
277
350
|
});
|
|
278
|
-
return {
|
|
279
|
-
play
|
|
280
|
-
|
|
281
|
-
off: emitter.off.bind(emitter),
|
|
282
|
-
once: emitter.once.bind(emitter),
|
|
283
|
-
events: emitter.events.bind(emitter)
|
|
284
|
-
};
|
|
351
|
+
return __spreadValues({
|
|
352
|
+
play
|
|
353
|
+
}, getEmitteryCallbacks(emitter));
|
|
285
354
|
}
|
|
286
355
|
/**
|
|
287
356
|
* Generate a unique ID suitable for a streaming context.
|
|
@@ -306,46 +375,51 @@ var audio_default = class extends Client {
|
|
|
306
375
|
connect() {
|
|
307
376
|
const url = constructWebsocketUrl(this.baseUrl);
|
|
308
377
|
url.searchParams.set("api_key", this.apiKey);
|
|
309
|
-
|
|
378
|
+
const emitter = new import_emittery.default();
|
|
379
|
+
this.socket = new import_partysocket.WebSocket(url.toString());
|
|
310
380
|
this.socket.onopen = () => {
|
|
311
381
|
this.isConnected = true;
|
|
382
|
+
emitter.emit("open");
|
|
312
383
|
};
|
|
313
384
|
this.socket.onclose = () => {
|
|
314
385
|
this.isConnected = false;
|
|
386
|
+
emitter.emit("close");
|
|
315
387
|
};
|
|
316
|
-
return new Promise(
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
388
|
+
return new Promise(
|
|
389
|
+
(resolve, reject) => {
|
|
390
|
+
var _a, _b, _c;
|
|
391
|
+
(_a = this.socket) == null ? void 0 : _a.addEventListener(
|
|
392
|
+
"open",
|
|
393
|
+
() => {
|
|
394
|
+
resolve(getEmitteryCallbacks(emitter));
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
once: true
|
|
398
|
+
}
|
|
399
|
+
);
|
|
400
|
+
const aborter = new AbortController();
|
|
401
|
+
(_b = this.socket) == null ? void 0 : _b.addEventListener(
|
|
402
|
+
"error",
|
|
403
|
+
() => {
|
|
404
|
+
aborter.abort();
|
|
405
|
+
reject(new Error("WebSocket failed to connect."));
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
signal: aborter.signal
|
|
409
|
+
}
|
|
410
|
+
);
|
|
411
|
+
(_c = this.socket) == null ? void 0 : _c.addEventListener(
|
|
412
|
+
"close",
|
|
413
|
+
() => {
|
|
414
|
+
aborter.abort();
|
|
415
|
+
reject(new Error("WebSocket closed before it could connect."));
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
signal: aborter.signal
|
|
419
|
+
}
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
);
|
|
349
423
|
}
|
|
350
424
|
/**
|
|
351
425
|
* Disconnect from the Cartesia streaming WebSocket.
|
|
@@ -358,33 +432,45 @@ var audio_default = class extends Client {
|
|
|
358
432
|
|
|
359
433
|
// src/react/index.ts
|
|
360
434
|
function useAudio({ apiKey, baseUrl }) {
|
|
361
|
-
if (typeof window === "undefined"
|
|
435
|
+
if (typeof window === "undefined") {
|
|
362
436
|
return {
|
|
363
437
|
stream: () => {
|
|
364
438
|
},
|
|
365
439
|
play: () => __async(this, null, function* () {
|
|
366
440
|
}),
|
|
441
|
+
download: () => null,
|
|
442
|
+
isConnected: false,
|
|
367
443
|
isPlaying: false,
|
|
444
|
+
isStreamed: false,
|
|
368
445
|
chunks: [],
|
|
369
446
|
messages: []
|
|
370
447
|
};
|
|
371
448
|
}
|
|
372
449
|
const audio = (0, import_react.useMemo)(() => {
|
|
450
|
+
if (!apiKey) {
|
|
451
|
+
return null;
|
|
452
|
+
}
|
|
373
453
|
const audio2 = new audio_default({ apiKey, baseUrl });
|
|
374
454
|
return audio2;
|
|
375
455
|
}, [apiKey, baseUrl]);
|
|
376
456
|
const streamReturn = (0, import_react.useRef)(null);
|
|
457
|
+
const [isStreamed, setIsStreamed] = (0, import_react.useState)(false);
|
|
377
458
|
const [isPlaying, setIsPlaying] = (0, import_react.useState)(false);
|
|
459
|
+
const [isConnected, setIsConnected] = (0, import_react.useState)(false);
|
|
378
460
|
const [chunks, setChunks] = (0, import_react.useState)([]);
|
|
379
461
|
const [messages, setMessages] = (0, import_react.useState)([]);
|
|
380
462
|
const stream = (0, import_react.useCallback)(
|
|
381
|
-
(options) => {
|
|
463
|
+
(options) => __async(this, null, function* () {
|
|
382
464
|
var _a;
|
|
383
465
|
streamReturn.current = (_a = audio == null ? void 0 : audio.stream(options)) != null ? _a : null;
|
|
466
|
+
if (!streamReturn.current) {
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
setMessages([]);
|
|
384
470
|
streamReturn.current.on(
|
|
385
471
|
"chunk",
|
|
386
|
-
({ chunks:
|
|
387
|
-
setChunks(
|
|
472
|
+
({ chunks: chunks3 }) => {
|
|
473
|
+
setChunks(chunks3);
|
|
388
474
|
}
|
|
389
475
|
);
|
|
390
476
|
streamReturn.current.on(
|
|
@@ -393,23 +479,46 @@ function useAudio({ apiKey, baseUrl }) {
|
|
|
393
479
|
setMessages((messages2) => [...messages2, message]);
|
|
394
480
|
}
|
|
395
481
|
);
|
|
396
|
-
|
|
482
|
+
const { chunks: chunks2 } = yield streamReturn.current.once("streamed");
|
|
483
|
+
setChunks(chunks2);
|
|
484
|
+
setIsStreamed(true);
|
|
485
|
+
}),
|
|
397
486
|
[audio]
|
|
398
487
|
);
|
|
488
|
+
const download = (0, import_react.useCallback)(() => {
|
|
489
|
+
if (!isStreamed) {
|
|
490
|
+
return null;
|
|
491
|
+
}
|
|
492
|
+
const audio2 = bufferToWav(SAMPLE_RATE, [base64ToArray(chunks)]);
|
|
493
|
+
return new Blob([audio2], { type: "audio/wav" });
|
|
494
|
+
}, [isStreamed, chunks]);
|
|
399
495
|
(0, import_react.useEffect)(() => {
|
|
400
|
-
|
|
496
|
+
let cleanup = () => {
|
|
497
|
+
};
|
|
498
|
+
function setupConnection() {
|
|
401
499
|
return __async(this, null, function* () {
|
|
402
500
|
try {
|
|
403
|
-
yield audio == null ? void 0 : audio.connect();
|
|
501
|
+
const connection = yield audio == null ? void 0 : audio.connect();
|
|
502
|
+
if (!connection) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
setIsConnected(true);
|
|
506
|
+
const unsubscribe = connection.on("close", () => {
|
|
507
|
+
setIsConnected(false);
|
|
508
|
+
});
|
|
509
|
+
return () => {
|
|
510
|
+
unsubscribe();
|
|
511
|
+
audio == null ? void 0 : audio.disconnect();
|
|
512
|
+
};
|
|
404
513
|
} catch (e) {
|
|
405
514
|
console.error(e);
|
|
406
515
|
}
|
|
407
|
-
return () => {
|
|
408
|
-
audio == null ? void 0 : audio.disconnect();
|
|
409
|
-
};
|
|
410
516
|
});
|
|
411
517
|
}
|
|
412
|
-
|
|
518
|
+
setupConnection().then((cleanupConnection) => {
|
|
519
|
+
cleanup = cleanupConnection;
|
|
520
|
+
});
|
|
521
|
+
return () => cleanup == null ? void 0 : cleanup();
|
|
413
522
|
}, [audio]);
|
|
414
523
|
const play = (0, import_react.useCallback)(
|
|
415
524
|
(bufferDuration = 0) => __async(this, null, function* () {
|
|
@@ -423,7 +532,16 @@ function useAudio({ apiKey, baseUrl }) {
|
|
|
423
532
|
}),
|
|
424
533
|
[isPlaying]
|
|
425
534
|
);
|
|
426
|
-
return {
|
|
535
|
+
return {
|
|
536
|
+
stream,
|
|
537
|
+
play,
|
|
538
|
+
download,
|
|
539
|
+
isPlaying,
|
|
540
|
+
isConnected,
|
|
541
|
+
isStreamed,
|
|
542
|
+
chunks,
|
|
543
|
+
messages
|
|
544
|
+
};
|
|
427
545
|
}
|
|
428
546
|
// Annotate the CommonJS export names for ESM import in node:
|
|
429
547
|
0 && (module.exports = {
|