assemblyai 4.5.0-beta.0 → 4.6.0

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 (48) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +53 -9
  3. package/dist/assemblyai.streaming.umd.js +317 -0
  4. package/dist/assemblyai.streaming.umd.min.js +1 -0
  5. package/dist/assemblyai.umd.js +160 -12
  6. package/dist/assemblyai.umd.min.js +1 -1
  7. package/dist/browser.mjs +154 -11
  8. package/dist/bun.mjs +154 -11
  9. package/dist/deno.mjs +154 -11
  10. package/dist/exports/index.d.ts +2 -0
  11. package/dist/exports/streaming.d.ts +4 -0
  12. package/dist/index.cjs +160 -12
  13. package/dist/index.mjs +160 -12
  14. package/dist/node.cjs +154 -11
  15. package/dist/node.mjs +154 -11
  16. package/dist/polyfills/fetch/default.d.ts +1 -0
  17. package/dist/polyfills/fetch/workerd.d.ts +1 -0
  18. package/dist/services/base.d.ts +1 -0
  19. package/dist/services/lemur/index.d.ts +8 -1
  20. package/dist/services/realtime/service.d.ts +60 -0
  21. package/dist/services/transcripts/index.d.ts +16 -3
  22. package/dist/streaming.browser.mjs +268 -0
  23. package/dist/streaming.cjs +306 -0
  24. package/dist/streaming.mjs +303 -0
  25. package/dist/types/index.d.ts +7 -0
  26. package/dist/types/openapi.generated.d.ts +75 -29
  27. package/dist/types/services/index.d.ts +7 -0
  28. package/dist/types/transcripts/index.d.ts +9 -0
  29. package/dist/utils/userAgent.d.ts +2 -0
  30. package/dist/workerd.mjs +751 -0
  31. package/docs/reference-types-from-js.md +27 -0
  32. package/package.json +57 -25
  33. package/src/exports/index.ts +2 -0
  34. package/src/exports/streaming.ts +4 -0
  35. package/src/polyfills/fetch/default.ts +3 -0
  36. package/src/polyfills/fetch/workerd.ts +1 -0
  37. package/src/services/base.ts +27 -7
  38. package/src/services/files/index.ts +19 -2
  39. package/src/services/index.ts +2 -1
  40. package/src/services/lemur/index.ts +12 -0
  41. package/src/services/realtime/service.ts +65 -0
  42. package/src/services/transcripts/index.ts +41 -4
  43. package/src/types/index.ts +9 -0
  44. package/src/types/openapi.generated.ts +224 -48
  45. package/src/types/services/index.ts +8 -0
  46. package/src/types/transcripts/index.ts +10 -0
  47. package/src/utils/path.ts +1 -0
  48. package/src/utils/userAgent.ts +51 -0
package/CHANGELOG.md CHANGED
@@ -1,7 +1,48 @@
1
1
  # Changelog
2
+
3
+ ## [4.6.0]
4
+
5
+ - Add more TSDoc comments for `RealtimeService` documentation
6
+ - Add new LeMUR models
7
+ - Add `TranscriptWebhookNotification` which is a union of `TranscriptReadyNotification` or `RedactedAudioNotification`
8
+ - Add `RedactedAudioNotification` which represents the body of the PII redacted audio webhook notification.
9
+
2
10
  ## [4.5.0]
3
11
 
12
+ - You can now retrieve previous LeMUR responses using `client.lemur.getResponse<LemurTask>("YOUR_REQUEST_ID")`.
13
+ - LeMUR functions now return `usage` with the number of `input_tokens` and `output_tokens`.
14
+
15
+ ## [4.4.7]
16
+
17
+ - Rename `TranscriptService.redactions` function to `TranscriptService.redactedAudio`.
18
+ - Add `TranscriptService.redactedAudioFile` function.
19
+ - Add `workerd` export to fix `cache` issue with `fetch` on Cloudflare Workers.
20
+
21
+ ## [4.4.6]
22
+
23
+ - Fix Rollup exports so \_\_SDK_VERSION\_\_ is properly replaced with the version of the SDK.
24
+
25
+ ## [4.4.5]
26
+
27
+ - Add new `PiiPolicy` enum values
28
+
29
+ ## [4.4.4]
30
+
31
+ - Add an export that only includes the Streaming STT code. You can use the export
32
+ - by importing `assemblyai/streaming`,
33
+ - or by loading the `assemblyai.streaming.umd.js` file, or `assemblyai.streaming.umd.min.js` file in a script-tag.
34
+ - Add new `EntityType` enum values
35
+
36
+ ## [4.4.3] - 2024-05-09
37
+
38
+ - Add react-native exports that resolve to the browser version of the library.
39
+
40
+ ## [4.4.2] - 2024-05-03
41
+
4
42
  ### Changed
43
+
44
+ - Caching is disabled for all HTTP request made by the SDK
45
+ - Accept data-URIs in `client.files.upload(dataUri)`, `client.transcripts.submit(audio: dataUri)`, `client.transcripts.transcribe(audio: dataUri)`.
5
46
  - Change how the WebSocket libraries are imported for better compatibility across frameworks and runtimes.
6
47
  The library no longer relies on a internal `#ws` import, and instead compiles the imports into the dist bundles.
7
48
  Browser builds will use the native `WebSocket`, other builds will use the `ws` package.
package/README.md CHANGED
@@ -53,6 +53,38 @@ const client = new AssemblyAI({
53
53
 
54
54
  You can now use the `client` object to interact with the AssemblyAI API.
55
55
 
56
+ ### Using a CDN
57
+
58
+ You can use automatic CDNs like [UNPKG](https://unpkg.com/) to load the library from a script tag.
59
+
60
+ - Replace `:version` with the desired version or `latest`.
61
+ - Remove `.min` to load the non-minified version.
62
+ - Remove `.streaming` to load the entire SDK. Keep `.streaming` to load the Streaming STT specific version.
63
+
64
+ ```html
65
+ <!-- Unminified full SDK -->
66
+ <script src="https://www.unpkg.com/assemblyai@:version/dist/assemblyai.umd.js"></script>
67
+ <!-- Minified full SDK -->
68
+ <script src="https://www.unpkg.com/assemblyai@:version/dist/assemblyai.umd.min.js"></script>
69
+ <!-- Unminified Streaming STT only -->
70
+ <script src="https://www.unpkg.com/assemblyai@:version/dist/assemblyai.streaming.umd.js"></script>
71
+ <!-- Minified Streaming STT only -->
72
+ <script src="https://www.unpkg.com/assemblyai@:version/dist/assemblyai.streaming.umd.min.js"></script>
73
+ ```
74
+
75
+ The script creates a global `assemblyai` variable containing all the services.
76
+ Here's how you create a `RealtimeTranscriber` object.
77
+
78
+ ```js
79
+ const { RealtimeTranscriber } = assemblyai;
80
+ const transcriber = new RealtimeTranscriber({
81
+ token: "[GENERATE TEMPORARY AUTH TOKEN IN YOUR API]",
82
+ ...
83
+ });
84
+ ```
85
+
86
+ For type support in your IDE, see [Reference types from JavaScript](./docs/reference-types-from-js.md).
87
+
56
88
  ## Speech-To-Text
57
89
 
58
90
  ### Transcribe audio and video files
@@ -227,18 +259,26 @@ const rt = client.realtime.transcriber({
227
259
  });
228
260
  ```
229
261
 
230
- You can also generate a temporary auth token for real-time.
231
-
232
- ```typescript
233
- const token = await client.realtime.createTemporaryToken({ expires_in = 60 });
234
- const rt = client.realtime.transcriber({
235
- token: token,
236
- });
237
- ```
238
-
239
262
  > [!WARNING]
240
263
  > Storing your API key in client-facing applications exposes your API key.
241
264
  > Generate a temporary auth token on the server and pass it to your client.
265
+ > _Server code_:
266
+ >
267
+ > ```typescript
268
+ > const token = await client.realtime.createTemporaryToken({ expires_in = 60 });
269
+ > // TODO: return token to client
270
+ > ```
271
+ >
272
+ > _Client code_:
273
+ >
274
+ > ```typescript
275
+ > import { RealtimeTranscriber } from "assemblyai"; // or "assemblyai/streaming"
276
+ > // TODO: implement getToken to retrieve token from server
277
+ > const token = await getToken();
278
+ > const rt = new RealtimeTranscriber({
279
+ > token,
280
+ > });
281
+ > ```
242
282
 
243
283
  You can configure the following events.
244
284
 
@@ -344,3 +384,7 @@ const response = await client.lemur.purgeRequestData(lemurResponse.request_id);
344
384
  ```
345
385
 
346
386
  </details>
387
+
388
+ ## Contributing
389
+
390
+ If you want to contribute to the JavaScript SDK, follow the guidelines in [CONTRIBUTING.md](./CONTRIBUTING.md).
@@ -0,0 +1,317 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.assemblyai = {}));
5
+ })(this, (function (exports) { 'use strict';
6
+
7
+ /******************************************************************************
8
+ Copyright (c) Microsoft Corporation.
9
+
10
+ Permission to use, copy, modify, and/or distribute this software for any
11
+ purpose with or without fee is hereby granted.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
14
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
18
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19
+ PERFORMANCE OF THIS SOFTWARE.
20
+ ***************************************************************************** */
21
+ /* global Reflect, Promise, SuppressedError, Symbol */
22
+
23
+
24
+ function __awaiter(thisArg, _arguments, P, generator) {
25
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
26
+ return new (P || (P = Promise))(function (resolve, reject) {
27
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
28
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
29
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
30
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
31
+ });
32
+ }
33
+
34
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
35
+ var e = new Error(message);
36
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
37
+ };
38
+
39
+ const { WritableStream } = typeof window !== "undefined"
40
+ ? window
41
+ : typeof global !== "undefined"
42
+ ? global
43
+ : globalThis;
44
+
45
+ var _a, _b;
46
+ const PolyfillWebSocket = (_b = (_a = WebSocket !== null && WebSocket !== void 0 ? WebSocket : global === null || global === void 0 ? void 0 : global.WebSocket) !== null && _a !== void 0 ? _a : window === null || window === void 0 ? void 0 : window.WebSocket) !== null && _b !== void 0 ? _b : self === null || self === void 0 ? void 0 : self.WebSocket;
47
+ const factory = (url, params) => {
48
+ if (params) {
49
+ return new PolyfillWebSocket(url, params);
50
+ }
51
+ return new PolyfillWebSocket(url);
52
+ };
53
+
54
+ var RealtimeErrorType;
55
+ (function (RealtimeErrorType) {
56
+ RealtimeErrorType[RealtimeErrorType["BadSampleRate"] = 4000] = "BadSampleRate";
57
+ RealtimeErrorType[RealtimeErrorType["AuthFailed"] = 4001] = "AuthFailed";
58
+ // Both InsufficientFunds and FreeAccount error use 4002
59
+ RealtimeErrorType[RealtimeErrorType["InsufficientFundsOrFreeAccount"] = 4002] = "InsufficientFundsOrFreeAccount";
60
+ RealtimeErrorType[RealtimeErrorType["NonexistentSessionId"] = 4004] = "NonexistentSessionId";
61
+ RealtimeErrorType[RealtimeErrorType["SessionExpired"] = 4008] = "SessionExpired";
62
+ RealtimeErrorType[RealtimeErrorType["ClosedSession"] = 4010] = "ClosedSession";
63
+ RealtimeErrorType[RealtimeErrorType["RateLimited"] = 4029] = "RateLimited";
64
+ RealtimeErrorType[RealtimeErrorType["UniqueSessionViolation"] = 4030] = "UniqueSessionViolation";
65
+ RealtimeErrorType[RealtimeErrorType["SessionTimeout"] = 4031] = "SessionTimeout";
66
+ RealtimeErrorType[RealtimeErrorType["AudioTooShort"] = 4032] = "AudioTooShort";
67
+ RealtimeErrorType[RealtimeErrorType["AudioTooLong"] = 4033] = "AudioTooLong";
68
+ RealtimeErrorType[RealtimeErrorType["BadJson"] = 4100] = "BadJson";
69
+ RealtimeErrorType[RealtimeErrorType["BadSchema"] = 4101] = "BadSchema";
70
+ RealtimeErrorType[RealtimeErrorType["TooManyStreams"] = 4102] = "TooManyStreams";
71
+ RealtimeErrorType[RealtimeErrorType["Reconnected"] = 4103] = "Reconnected";
72
+ RealtimeErrorType[RealtimeErrorType["ReconnectAttemptsExhausted"] = 1013] = "ReconnectAttemptsExhausted";
73
+ })(RealtimeErrorType || (RealtimeErrorType = {}));
74
+ const RealtimeErrorMessages = {
75
+ [RealtimeErrorType.BadSampleRate]: "Sample rate must be a positive integer",
76
+ [RealtimeErrorType.AuthFailed]: "Not Authorized",
77
+ [RealtimeErrorType.InsufficientFundsOrFreeAccount]: "Insufficient funds or you are using a free account. This feature is paid-only and requires you to add a credit card. Please visit https://assemblyai.com/dashboard/ to add a credit card to your account.",
78
+ [RealtimeErrorType.NonexistentSessionId]: "Session ID does not exist",
79
+ [RealtimeErrorType.SessionExpired]: "Session has expired",
80
+ [RealtimeErrorType.ClosedSession]: "Session is closed",
81
+ [RealtimeErrorType.RateLimited]: "Rate limited",
82
+ [RealtimeErrorType.UniqueSessionViolation]: "Unique session violation",
83
+ [RealtimeErrorType.SessionTimeout]: "Session Timeout",
84
+ [RealtimeErrorType.AudioTooShort]: "Audio too short",
85
+ [RealtimeErrorType.AudioTooLong]: "Audio too long",
86
+ [RealtimeErrorType.BadJson]: "Bad JSON",
87
+ [RealtimeErrorType.BadSchema]: "Bad schema",
88
+ [RealtimeErrorType.TooManyStreams]: "Too many streams",
89
+ [RealtimeErrorType.Reconnected]: "Reconnected",
90
+ [RealtimeErrorType.ReconnectAttemptsExhausted]: "Reconnect attempts exhausted",
91
+ };
92
+ class RealtimeError extends Error {
93
+ }
94
+
95
+ const defaultRealtimeUrl = "wss://api.assemblyai.com/v2/realtime/ws";
96
+ const forceEndOfUtteranceMessage = `{"force_end_utterance":true}`;
97
+ const terminateSessionMessage = `{"terminate_session":true}`;
98
+ /**
99
+ * RealtimeTranscriber connects to the Streaming Speech-to-Text API and lets you transcribe audio in real-time.
100
+ */
101
+ class RealtimeTranscriber {
102
+ /**
103
+ * Create a new RealtimeTranscriber.
104
+ * @param params - Parameters to configure the RealtimeTranscriber
105
+ */
106
+ constructor(params) {
107
+ var _a, _b;
108
+ this.listeners = {};
109
+ this.realtimeUrl = (_a = params.realtimeUrl) !== null && _a !== void 0 ? _a : defaultRealtimeUrl;
110
+ this.sampleRate = (_b = params.sampleRate) !== null && _b !== void 0 ? _b : 16000;
111
+ this.wordBoost = params.wordBoost;
112
+ this.encoding = params.encoding;
113
+ this.endUtteranceSilenceThreshold = params.endUtteranceSilenceThreshold;
114
+ this.disablePartialTranscripts = params.disablePartialTranscripts;
115
+ if ("token" in params && params.token)
116
+ this.token = params.token;
117
+ if ("apiKey" in params && params.apiKey)
118
+ this.apiKey = params.apiKey;
119
+ if (!(this.token || this.apiKey)) {
120
+ throw new Error("API key or temporary token is required.");
121
+ }
122
+ }
123
+ connectionUrl() {
124
+ const url = new URL(this.realtimeUrl);
125
+ if (url.protocol !== "wss:") {
126
+ throw new Error("Invalid protocol, must be wss");
127
+ }
128
+ const searchParams = new URLSearchParams();
129
+ if (this.token) {
130
+ searchParams.set("token", this.token);
131
+ }
132
+ searchParams.set("sample_rate", this.sampleRate.toString());
133
+ if (this.wordBoost && this.wordBoost.length > 0) {
134
+ searchParams.set("word_boost", JSON.stringify(this.wordBoost));
135
+ }
136
+ if (this.encoding) {
137
+ searchParams.set("encoding", this.encoding);
138
+ }
139
+ searchParams.set("enable_extra_session_information", "true");
140
+ if (this.disablePartialTranscripts) {
141
+ searchParams.set("disable_partial_transcripts", this.disablePartialTranscripts.toString());
142
+ }
143
+ url.search = searchParams.toString();
144
+ return url;
145
+ }
146
+ /**
147
+ * Add a listener for an event.
148
+ * @param event - The event to listen for.
149
+ * @param listener - The function to call when the event is emitted.
150
+ */
151
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
152
+ on(event, listener) {
153
+ this.listeners[event] = listener;
154
+ }
155
+ /**
156
+ * Connect to the server and begin a new session.
157
+ * @returns A promise that resolves when the connection is established and the session begins.
158
+ */
159
+ connect() {
160
+ return new Promise((resolve) => {
161
+ if (this.socket) {
162
+ throw new Error("Already connected");
163
+ }
164
+ const url = this.connectionUrl();
165
+ if (this.token) {
166
+ this.socket = factory(url.toString());
167
+ }
168
+ else {
169
+ this.socket = factory(url.toString(), {
170
+ headers: { Authorization: this.apiKey },
171
+ });
172
+ }
173
+ this.socket.binaryType = "arraybuffer";
174
+ this.socket.onopen = () => {
175
+ if (this.endUtteranceSilenceThreshold === undefined ||
176
+ this.endUtteranceSilenceThreshold === null) {
177
+ return;
178
+ }
179
+ this.configureEndUtteranceSilenceThreshold(this.endUtteranceSilenceThreshold);
180
+ };
181
+ this.socket.onclose = ({ code, reason }) => {
182
+ var _a, _b;
183
+ if (!reason) {
184
+ if (code in RealtimeErrorType) {
185
+ reason = RealtimeErrorMessages[code];
186
+ }
187
+ }
188
+ (_b = (_a = this.listeners).close) === null || _b === void 0 ? void 0 : _b.call(_a, code, reason);
189
+ };
190
+ this.socket.onerror = (event) => {
191
+ var _a, _b, _c, _d;
192
+ if (event.error)
193
+ (_b = (_a = this.listeners).error) === null || _b === void 0 ? void 0 : _b.call(_a, event.error);
194
+ else
195
+ (_d = (_c = this.listeners).error) === null || _d === void 0 ? void 0 : _d.call(_c, new Error(event.message));
196
+ };
197
+ this.socket.onmessage = ({ data }) => {
198
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
199
+ const message = JSON.parse(data.toString());
200
+ if ("error" in message) {
201
+ (_b = (_a = this.listeners).error) === null || _b === void 0 ? void 0 : _b.call(_a, new RealtimeError(message.error));
202
+ return;
203
+ }
204
+ switch (message.message_type) {
205
+ case "SessionBegins": {
206
+ const openObject = {
207
+ sessionId: message.session_id,
208
+ expiresAt: new Date(message.expires_at),
209
+ };
210
+ resolve(openObject);
211
+ (_d = (_c = this.listeners).open) === null || _d === void 0 ? void 0 : _d.call(_c, openObject);
212
+ break;
213
+ }
214
+ case "PartialTranscript": {
215
+ // message.created is actually a string when coming from the socket
216
+ message.created = new Date(message.created);
217
+ (_f = (_e = this.listeners).transcript) === null || _f === void 0 ? void 0 : _f.call(_e, message);
218
+ (_h = (_g = this.listeners)["transcript.partial"]) === null || _h === void 0 ? void 0 : _h.call(_g, message);
219
+ break;
220
+ }
221
+ case "FinalTranscript": {
222
+ // message.created is actually a string when coming from the socket
223
+ message.created = new Date(message.created);
224
+ (_k = (_j = this.listeners).transcript) === null || _k === void 0 ? void 0 : _k.call(_j, message);
225
+ (_m = (_l = this.listeners)["transcript.final"]) === null || _m === void 0 ? void 0 : _m.call(_l, message);
226
+ break;
227
+ }
228
+ case "SessionInformation": {
229
+ (_p = (_o = this.listeners).session_information) === null || _p === void 0 ? void 0 : _p.call(_o, message);
230
+ break;
231
+ }
232
+ case "SessionTerminated": {
233
+ (_q = this.sessionTerminatedResolve) === null || _q === void 0 ? void 0 : _q.call(this);
234
+ break;
235
+ }
236
+ }
237
+ };
238
+ });
239
+ }
240
+ /**
241
+ * Send audio data to the server.
242
+ * @param audio - The audio data to send to the server.
243
+ */
244
+ sendAudio(audio) {
245
+ this.send(audio);
246
+ }
247
+ /**
248
+ * Create a writable stream that can be used to send audio data to the server.
249
+ * @returns A writable stream that can be used to send audio data to the server.
250
+ */
251
+ stream() {
252
+ return new WritableStream({
253
+ write: (chunk) => {
254
+ this.sendAudio(chunk);
255
+ },
256
+ });
257
+ }
258
+ /**
259
+ * Manually end an utterance
260
+ */
261
+ forceEndUtterance() {
262
+ this.send(forceEndOfUtteranceMessage);
263
+ }
264
+ /**
265
+ * Configure the threshold for how long to wait before ending an utterance. Default is 700ms.
266
+ * @param threshold - The duration of the end utterance silence threshold in milliseconds.
267
+ * This value must be an integer between 0 and 20_000.
268
+ */
269
+ configureEndUtteranceSilenceThreshold(threshold) {
270
+ this.send(`{"end_utterance_silence_threshold":${threshold}}`);
271
+ }
272
+ send(data) {
273
+ if (!this.socket || this.socket.readyState !== this.socket.OPEN) {
274
+ throw new Error("Socket is not open for communication");
275
+ }
276
+ this.socket.send(data);
277
+ }
278
+ /**
279
+ * Close the connection to the server.
280
+ * @param waitForSessionTermination - If true, the method will wait for the session to be terminated before closing the connection.
281
+ * While waiting for the session to be terminated, you will receive the final transcript and session information.
282
+ */
283
+ close() {
284
+ return __awaiter(this, arguments, void 0, function* (waitForSessionTermination = true) {
285
+ var _a;
286
+ if (this.socket) {
287
+ if (this.socket.readyState === this.socket.OPEN) {
288
+ if (waitForSessionTermination) {
289
+ const sessionTerminatedPromise = new Promise((resolve) => {
290
+ this.sessionTerminatedResolve = resolve;
291
+ });
292
+ this.socket.send(terminateSessionMessage);
293
+ yield sessionTerminatedPromise;
294
+ }
295
+ else {
296
+ this.socket.send(terminateSessionMessage);
297
+ }
298
+ }
299
+ if ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.removeAllListeners)
300
+ this.socket.removeAllListeners();
301
+ this.socket.close();
302
+ }
303
+ this.listeners = {};
304
+ this.socket = undefined;
305
+ });
306
+ }
307
+ }
308
+ /**
309
+ * @deprecated Use RealtimeTranscriber instead
310
+ */
311
+ class RealtimeService extends RealtimeTranscriber {
312
+ }
313
+
314
+ exports.RealtimeService = RealtimeService;
315
+ exports.RealtimeTranscriber = RealtimeTranscriber;
316
+
317
+ }));
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).assemblyai={})}(this,(function(e){"use strict";function t(e,t,s,i){return new(s||(s=Promise))((function(o,n){function r(e){try{l(i.next(e))}catch(e){n(e)}}function a(e){try{l(i.throw(e))}catch(e){n(e)}}function l(e){var t;e.done?o(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(r,a)}l((i=i.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const{WritableStream:s}="undefined"!=typeof window?window:"undefined"!=typeof global?global:globalThis;var i,o;const n=null!==(o=null!==(i=null!==WebSocket&&void 0!==WebSocket?WebSocket:null===global||void 0===global?void 0:global.WebSocket)&&void 0!==i?i:null===window||void 0===window?void 0:window.WebSocket)&&void 0!==o?o:null===self||void 0===self?void 0:self.WebSocket,r=(e,t)=>t?new n(e,t):new n(e);var a;!function(e){e[e.BadSampleRate=4e3]="BadSampleRate",e[e.AuthFailed=4001]="AuthFailed",e[e.InsufficientFundsOrFreeAccount=4002]="InsufficientFundsOrFreeAccount",e[e.NonexistentSessionId=4004]="NonexistentSessionId",e[e.SessionExpired=4008]="SessionExpired",e[e.ClosedSession=4010]="ClosedSession",e[e.RateLimited=4029]="RateLimited",e[e.UniqueSessionViolation=4030]="UniqueSessionViolation",e[e.SessionTimeout=4031]="SessionTimeout",e[e.AudioTooShort=4032]="AudioTooShort",e[e.AudioTooLong=4033]="AudioTooLong",e[e.BadJson=4100]="BadJson",e[e.BadSchema=4101]="BadSchema",e[e.TooManyStreams=4102]="TooManyStreams",e[e.Reconnected=4103]="Reconnected",e[e.ReconnectAttemptsExhausted=1013]="ReconnectAttemptsExhausted"}(a||(a={}));const l={[a.BadSampleRate]:"Sample rate must be a positive integer",[a.AuthFailed]:"Not Authorized",[a.InsufficientFundsOrFreeAccount]:"Insufficient funds or you are using a free account. This feature is paid-only and requires you to add a credit card. Please visit https://assemblyai.com/dashboard/ to add a credit card to your account.",[a.NonexistentSessionId]:"Session ID does not exist",[a.SessionExpired]:"Session has expired",[a.ClosedSession]:"Session is closed",[a.RateLimited]:"Rate limited",[a.UniqueSessionViolation]:"Unique session violation",[a.SessionTimeout]:"Session Timeout",[a.AudioTooShort]:"Audio too short",[a.AudioTooLong]:"Audio too long",[a.BadJson]:"Bad JSON",[a.BadSchema]:"Bad schema",[a.TooManyStreams]:"Too many streams",[a.Reconnected]:"Reconnected",[a.ReconnectAttemptsExhausted]:"Reconnect attempts exhausted"};class c extends Error{}const d='{"terminate_session":true}';class h{constructor(e){var t,s;if(this.listeners={},this.realtimeUrl=null!==(t=e.realtimeUrl)&&void 0!==t?t:"wss://api.assemblyai.com/v2/realtime/ws",this.sampleRate=null!==(s=e.sampleRate)&&void 0!==s?s:16e3,this.wordBoost=e.wordBoost,this.encoding=e.encoding,this.endUtteranceSilenceThreshold=e.endUtteranceSilenceThreshold,this.disablePartialTranscripts=e.disablePartialTranscripts,"token"in e&&e.token&&(this.token=e.token),"apiKey"in e&&e.apiKey&&(this.apiKey=e.apiKey),!this.token&&!this.apiKey)throw new Error("API key or temporary token is required.")}connectionUrl(){const e=new URL(this.realtimeUrl);if("wss:"!==e.protocol)throw new Error("Invalid protocol, must be wss");const t=new URLSearchParams;return this.token&&t.set("token",this.token),t.set("sample_rate",this.sampleRate.toString()),this.wordBoost&&this.wordBoost.length>0&&t.set("word_boost",JSON.stringify(this.wordBoost)),this.encoding&&t.set("encoding",this.encoding),t.set("enable_extra_session_information","true"),this.disablePartialTranscripts&&t.set("disable_partial_transcripts",this.disablePartialTranscripts.toString()),e.search=t.toString(),e}on(e,t){this.listeners[e]=t}connect(){return new Promise((e=>{if(this.socket)throw new Error("Already connected");const t=this.connectionUrl();this.token?this.socket=r(t.toString()):this.socket=r(t.toString(),{headers:{Authorization:this.apiKey}}),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{void 0!==this.endUtteranceSilenceThreshold&&null!==this.endUtteranceSilenceThreshold&&this.configureEndUtteranceSilenceThreshold(this.endUtteranceSilenceThreshold)},this.socket.onclose=({code:e,reason:t})=>{var s,i;t||e in a&&(t=l[e]),null===(i=(s=this.listeners).close)||void 0===i||i.call(s,e,t)},this.socket.onerror=e=>{var t,s,i,o;e.error?null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e.error):null===(o=(i=this.listeners).error)||void 0===o||o.call(i,new Error(e.message))},this.socket.onmessage=({data:t})=>{var s,i,o,n,r,a,l,d,h,u,p,m,S,f,v;const w=JSON.parse(t.toString());if("error"in w)null===(i=(s=this.listeners).error)||void 0===i||i.call(s,new c(w.error));else switch(w.message_type){case"SessionBegins":{const t={sessionId:w.session_id,expiresAt:new Date(w.expires_at)};e(t),null===(n=(o=this.listeners).open)||void 0===n||n.call(o,t);break}case"PartialTranscript":w.created=new Date(w.created),null===(a=(r=this.listeners).transcript)||void 0===a||a.call(r,w),null===(d=(l=this.listeners)["transcript.partial"])||void 0===d||d.call(l,w);break;case"FinalTranscript":w.created=new Date(w.created),null===(u=(h=this.listeners).transcript)||void 0===u||u.call(h,w),null===(m=(p=this.listeners)["transcript.final"])||void 0===m||m.call(p,w);break;case"SessionInformation":null===(f=(S=this.listeners).session_information)||void 0===f||f.call(S,w);break;case"SessionTerminated":null===(v=this.sessionTerminatedResolve)||void 0===v||v.call(this)}}}))}sendAudio(e){this.send(e)}stream(){return new s({write:e=>{this.sendAudio(e)}})}forceEndUtterance(){this.send('{"force_end_utterance":true}')}configureEndUtteranceSilenceThreshold(e){this.send(`{"end_utterance_silence_threshold":${e}}`)}send(e){if(!this.socket||this.socket.readyState!==this.socket.OPEN)throw new Error("Socket is not open for communication");this.socket.send(e)}close(){return t(this,arguments,void 0,(function*(e=!0){var t;if(this.socket){if(this.socket.readyState===this.socket.OPEN)if(e){const e=new Promise((e=>{this.sessionTerminatedResolve=e}));this.socket.send(d),yield e}else this.socket.send(d);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}e.RealtimeService=class extends h{},e.RealtimeTranscriber=h}));