diff --git a/README.md b/README.md index d8a1da89..6e4becaa 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ Official JavaScript SDK for [Deepgram](https://www.deepgram.com/). Power your apps with world-class speech and Language AI models. +- [Migrating from v2](#migrating-from-v2) - [Installation](#installation) - [UMD](#umd) - [ESM](#esm) @@ -11,9 +12,13 @@ Official JavaScript SDK for [Deepgram](https://www.deepgram.com/). Power your ap - [Getting an API Key](#getting-an-api-key) - [Scoped Configuration](#scoped-configuration) - [Rest requests in the browser](#rest-requests-in-the-browser) -- [Transcription](#transcription) +- [Transcription (Synchronous)](#transcription-synchronous) - [Remote Files](#remote-files) - [Local Files](#local-files) +- [Transcription (Asynchronous / Callbacks)](#transcription-asynchronous--callbacks) + - [Remote Files](#remote-files-1) + - [Local Files](#local-files-1) +- [Transcription (Live / Streaming)](#transcription-live--streaming) - [Live Audio](#live-audio) - [Transcribing to captions](#transcribing-to-captions) - [Projects](#projects) @@ -51,8 +56,13 @@ Official JavaScript SDK for [Deepgram](https://www.deepgram.com/). Power your ap - [Create On-Prem credentials](#create-on-prem-credentials) - [Delete On-Prem credentials](#delete-on-prem-credentials) - [Development and Contributing](#development-and-contributing) + - [Debugging and making changes locally](#debugging-and-making-changes-locally) - [Getting Help](#getting-help) +# Migrating from v2 + +We have published [a migration guide on our docs](https://developers.deepgram.com/docs/js-sdk-v2-to-v3-migration-guide), showing how to move from v2 to v3. + # Installation You can install this SDK directly from [npm](https://www.npmjs.com/package/@deepgram/sdk). @@ -146,7 +156,7 @@ const deepgram = createClient("proxy", { Your proxy service should replace the Authorization header with `Authorization: token ` and return results verbatim to the SDK. -# Transcription +# Transcription (Synchronous) ## Remote Files @@ -187,6 +197,58 @@ const { result, error } = await deepgram.listen.prerecorded.transcribeFile( [See our API reference for more info](https://developers.deepgram.com/reference/pre-recorded). +# Transcription (Asynchronous / Callbacks) + +## Remote Files + +```js +import { CallbackUrl } from "@deepgram/sdk"; + +const { result, error } = await deepgram.listen.prerecorded.transcribeUrlCallback( + { + url: "https://dpgr.am/spacewalk.wav", + }, + new CallbackUrl("http://callback/endpoint"), + { + model: "nova", + } +); +``` + +[See our API reference for more info](https://developers.deepgram.com/reference/pre-recorded). + +## Local Files + +```js +import { CallbackUrl } from "@deepgram/sdk"; + +const { result, error } = await deepgram.listen.prerecorded.transcribeFileCallback( + fs.createReadStream("./examples/spacewalk.wav"), + new CallbackUrl("http://callback/endpoint"), + { + model: "nova", + } +); +``` + +or + +```js +import { CallbackUrl } from "@deepgram/sdk"; + +const { result, error } = await deepgram.listen.prerecorded.transcribeFileCallback( + fs.readFileSync("./examples/spacewalk.wav"), + new CallbackUrl("http://callback/endpoint"), + { + model: "nova", + } +); +``` + +[See our API reference for more info](https://developers.deepgram.com/reference/pre-recorded). + +# Transcription (Live / Streaming) + ## Live Audio ```js @@ -499,6 +561,10 @@ To make sure our community is safe for all, be sure to review and agree to our [Code of Conduct](./CODE_OF_CONDUCT.md). Then see the [Contribution](./CONTRIBUTING.md) guidelines for more information. +## Debugging and making changes locally + +If you want to make local changes to the SDK and run the [`examples/`](./examples/), you'll need to `npm run build` first, to ensure that your changes are included in the examples that are running. + # Getting Help We love to hear from you so if you have questions, comments or find a bug in the diff --git a/package-lock.json b/package-lock.json index 128e531c..dd5f11f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,11 +10,11 @@ "license": "MIT", "dependencies": { "@deepgram/captions": "^1.1.1", + "@types/websocket": "^1.0.9", "cross-fetch": "^3.1.5", "deepmerge": "^4.3.1", "events": "^3.3.0", - "isomorphic-ws": "^5.0.0", - "ws": "^8.14.2" + "websocket": "^1.0.34" }, "devDependencies": { "@commitlint/cli": "^17.6.7", @@ -23,7 +23,6 @@ "@flydotio/dockerfile": "^0.4.10", "@types/chai": "^4.3.5", "@types/mocha": "^9.1.1", - "@types/ws": "^8.5.6", "chai": "^4.3.7", "cross-env": "^7.0.3", "husky": "^4.3.0", @@ -804,9 +803,9 @@ } }, "node_modules/@deepgram/captions": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@deepgram/captions/-/captions-1.1.1.tgz", - "integrity": "sha512-hQ3UoV/VBrCYn11MpYo7uYaswjW8pvHDUbhiXBpiTkddp0Ojn1QmxzmWSYRCm/6vs/2aTS0gOG0ZlR2pLHx/UQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@deepgram/captions/-/captions-1.2.0.tgz", + "integrity": "sha512-8B1C/oTxTxyHlSFubAhNRgCbQ2SQ5wwvtlByn8sDYZvdDtdn/VE2yEPZ4BvUnrKWmsbTQY6/ooLV+9Ka2qmDSQ==", "dependencies": { "dayjs": "^1.11.10" }, @@ -1156,8 +1155,7 @@ "node_modules/@types/node": { "version": "14.18.53", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.53.tgz", - "integrity": "sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A==", - "dev": true + "integrity": "sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -1171,11 +1169,10 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "node_modules/@types/ws": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.6.tgz", - "integrity": "sha512-8B5EO9jLVCy+B58PLHvLDuOD8DRVMgQzq8d55SjLCOn9kqGyqOvy27exVaTio1q1nX5zLu8/6N0n2ThSxOM6tg==", - "dev": true, + "node_modules/@types/websocket": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/websocket/-/websocket-1.0.9.tgz", + "integrity": "sha512-xrMBdqdKdlE+7L9Wg2PQblIkZGSgiMlEoP6UAaYKMHbbxqCJ6PV/pTZ2RcMcSSERurU2TtGbmO4lqpFOJd01ww==", "dependencies": { "@types/node": "*" } @@ -1704,6 +1701,18 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/caching-transform": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", @@ -2159,6 +2168,15 @@ "node": ">= 8" } }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "node_modules/dargs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", @@ -2521,12 +2539,45 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -2644,6 +2695,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3643,8 +3707,7 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, "node_modules/is-unicode-supported": { "version": "0.1.0", @@ -3694,14 +3757,6 @@ "node": ">=0.10.0" } }, - "node_modules/isomorphic-ws": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", - "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", - "peerDependencies": { - "ws": "*" - } - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -4563,6 +4618,11 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -4588,6 +4648,16 @@ } } }, + "node_modules/node-gyp-build": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.7.0.tgz", + "integrity": "sha512-PbZERfeFdrHQOOXiAKOY0VPbykZy90ndPKk0d+CFDegTKmWp1VgOTz2xACVbr1BjCWxrQp68CXtvNsveFhqDJg==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -6776,6 +6846,11 @@ "node": ">=0.3.1" } }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -6866,7 +6941,6 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, "dependencies": { "is-typedarray": "^1.0.0" } @@ -6985,6 +7059,18 @@ "punycode": "^2.1.0" } }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -7177,6 +7263,35 @@ "node": ">=10.13.0" } }, + "node_modules/websocket": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", + "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -7331,26 +7446,6 @@ "typedarray-to-buffer": "^3.1.5" } }, - "node_modules/ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -7360,6 +7455,14 @@ "node": ">=10" } }, + "node_modules/yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", + "engines": { + "node": ">=0.10.32" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/package.json b/package.json index 7801927d..ebece6d8 100644 --- a/package.json +++ b/package.json @@ -52,11 +52,11 @@ }, "dependencies": { "@deepgram/captions": "^1.1.1", + "@types/websocket": "^1.0.9", "cross-fetch": "^3.1.5", "deepmerge": "^4.3.1", "events": "^3.3.0", - "isomorphic-ws": "^5.0.0", - "ws": "^8.14.2" + "websocket": "^1.0.34" }, "devDependencies": { "@commitlint/cli": "^17.6.7", @@ -65,7 +65,6 @@ "@flydotio/dockerfile": "^0.4.10", "@types/chai": "^4.3.5", "@types/mocha": "^9.1.1", - "@types/ws": "^8.5.6", "chai": "^4.3.7", "cross-env": "^7.0.3", "husky": "^4.3.0", diff --git a/src/index.ts b/src/index.ts index 716f5e73..0c859252 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,8 +18,16 @@ export * from "./lib/types"; export * from "./lib/enums"; export * from "./lib/constants"; export * from "./lib/errors"; +export * from "./lib/helpers"; /** - * Captions. + * Captions. These will be tree-shaken if unused. + * + * @see https://github.com/deepgram/deepgram-node-captions + * + * import/export declarations don't do anything but set up an alias to the + * exported variable, they do not count as a "use". Given their semantics, + * they are tracked specially by any bundler and will not adversely affect + * tree-shaking. */ export { webvtt, srt } from "@deepgram/captions"; diff --git a/src/packages/LiveClient.ts b/src/packages/LiveClient.ts index cda1d241..ebc1e861 100644 --- a/src/packages/LiveClient.ts +++ b/src/packages/LiveClient.ts @@ -1,9 +1,9 @@ import { AbstractWsClient } from "./AbstractWsClient"; -import { appendSearchParams, isServer } from "../lib/helpers"; +import { appendSearchParams } from "../lib/helpers"; import { DeepgramError } from "../lib/errors"; import { DEFAULT_OPTIONS } from "../lib/constants"; import { LiveConnectionState, LiveTranscriptionEvents } from "../lib/enums"; -import WebSocket from "isomorphic-ws"; +import { w3cwebsocket } from "websocket"; import type { LiveSchema, @@ -14,7 +14,7 @@ import type { } from "../lib/types"; export class LiveClient extends AbstractWsClient { - private _socket: WebSocket; + private _socket: w3cwebsocket; constructor( protected key: string, @@ -28,22 +28,13 @@ export class LiveClient extends AbstractWsClient { url.protocol = url.protocol.toLowerCase().replace(/(http)(s)?/gi, "ws$2"); appendSearchParams(url.searchParams, this.transcriptionOptions); - if (isServer()) { - this._socket = new WebSocket(url.toString(), { - headers: { - Authorization: `token ${this.key}`, - ...this.options?.global?.headers, - }, - }); - } else { - this._socket = new WebSocket(url.toString(), ["token", this.key]); - } + this._socket = new w3cwebsocket(url.toString(), ["token", this.key]); this._socket.onopen = () => { this.emit(LiveTranscriptionEvents.Open, this); }; - this._socket.onclose = (event: WebSocket.CloseEvent) => { + this._socket.onclose = (event: any) => { /** * changing the event.target to any to access the private _req * property that isn't available on the WebSocket.CloseEvent type