Skip to content

Commit

Permalink
Merge pull request #24 from AssemblyAI/E07417BDFEA3614F5967B1520F8B2F61
Browse files Browse the repository at this point in the history
Release 4.0.0-beta.0
  • Loading branch information
Swimburger committed Nov 28, 2023
2 parents f473053 + dbdfdd4 commit a784af9
Show file tree
Hide file tree
Showing 16 changed files with 231 additions and 71 deletions.
26 changes: 18 additions & 8 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,25 @@
"root": true,
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"parser": "@typescript-eslint/parser",
"parserOptions": { "project": ["./tsconfig.json"] },
"parserOptions": {
"project": ["./tsconfig.json"]
},
"plugins": ["@typescript-eslint"],
"rules": {},
"ignorePatterns": [
"/*.js",
"/*.ts",
"tests",
"dist",
"node_modules",
"scripts"
"ignorePatterns": ["/*.js", "/*.ts", "dist", "node_modules"],
"overrides": [
{
"files": ["tests/**/*"],
"parserOptions": {
"project": ["./tsconfig.test.json"]
}
},

{
"files": ["scripts/**/*"],
"parserOptions": {
"project": ["./tsconfig.scripts.json"]
}
}
]
}
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## [4.0.0]

### Added

- Add `browser` and `browser:min` exports, at `dist/index.umd.js` and `dist/index.umd.min.js`. These exports are browser compatible versions of the SDK, with a few limitations. You can't use the file system and you have to use a temporary auth token with the real-time transcriber.

### Changed

- `RealtimeService.sendAudio` accepts audio via type `ArrayBufferLike`.
- **Breaking**: `RealtimeService.stream` returns a [WHATWG Streams Standard stream](https://nodejs.org/api/webstreams.html), instead of a Node stream. In the browser, the native web standard stream will be used.
- `ws` is used as the WebSocket client as before, but in the browser, the native WebSocket client is used.
- Rename Node SDK to JavaScript SDK as the SDK is compatible with more runtimes now.

## [3.1.1] - 2023-11-21

### Added
Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
[![Discord](https://img.shields.io/discord/875120158014853141?logo=discord&label=Discord&link=https%3A%2F%2Fdiscord.com%2Fchannels%2F875120158014853141&style=social)
](https://assemblyai.com/discord)

# AssemblyAI Node.js SDK
# AssemblyAI JavaScript SDK

The AssemblyAI Node.js SDK provides an easy-to-use interface for interacting with the AssemblyAI API,
The AssemblyAI JavaScript SDK provides an easy-to-use interface for interacting with the AssemblyAI API,
which supports async and real-time transcription, as well as the latest LeMUR models.
It is written primarily for Node.js in TypeScript with all types exported, but also [compatible with other runtimes](./docs/compat.md).

## Installation

Expand Down Expand Up @@ -51,7 +52,7 @@ You can now use the `client` object to interact with the AssemblyAI API.

## Create a transcript

When you create a transcript, you can either pass in a URL to an audio file, or upload a file directly.
When you create a transcript, you can either pass in a URL to an audio file or upload a file directly.

```javascript
// Transcribe file at remote URL
Expand Down Expand Up @@ -242,10 +243,10 @@ getAudio((chunk) => {
});
```

Or send audio data via a stream by piping to the realtime stream.
Or send audio data via a stream by piping to the real-time stream.

```typescript
audioStream.pipe(rt.stream());
audioStream.pipeTo(rt.stream());
```

Close the connection when you're finished.
Expand Down
59 changes: 59 additions & 0 deletions docs/compat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# SDK Compatibility

The JavaScript SDK is developed for Node.js but is also compatible with other runtimes
such as the browser, Deno, Bun, Cloudflare Workers, etc.

## Browser compatibility

To make the SDK compatible with the browser, the SDK aims to use web standards as much as possible.
However, there are still incompatibilities between Node.js and the browser.

- `RealtimeService` doesn't support the AssemblyAI API key in the browser.
Instead, you have to generate a temporary auth token using `client.realtime.createTemporaryToken`, and pass in the resulting token to the real-time transcriber.

Generate a temporary auth token on the server.

```js
import { AssemblyAI } from "assemblyai"
// Ideally, to avoid embedding your API key client side,
// you generate this token on the server, and pass it to the client via an API.
const client = new AssemblyAI({ apiKey: "YOUR_API_KEY" });
const token = await client.realtime.createTemporaryToken({ expires_in = 480 });
```

> [!NOTE]
> We recommend generating the token on the server, so you don't embed your AssemblyAI API key in your client app.
> If you embed the API key on the client, everyone can see it and use it for themselves.
Then pass the token via an API to the client.
On the client, create an instance of `RealtimeService` using the token.

```js
import { RealtimeService } from "assemblyai";
// or the following if you're using UMD
// const { RealtimeService } = assemblyai;

const token = getToken(); // getToken is a function for you to implement

const rt = new RealtimeService({
token: token,
});
```

- You can't pass local audio file paths to `client.files.upload`, `client.transcripts.transcribe`, and `client.transcripts.submit`. If you do, you'll get the following error: "Function is not supported in this environment.".
If you want to transcribe audio files, you must use a public URL, a stream, or a buffer.

> [!WARNING]
> The SDK is usable from the browser, but we strongly recommend you don't embed the AssemblyAI API key into your client apps.
> If you embed the API key on the client, everyone can see it and use it for themselves.
> Instead, create use the SDK on the server and provide APIs for your client to call.
## Deno, Bun, Cloudflare Workers, etc.

Most server-side JavaScript runtimes include a compatibility layer with Node.js.
Our SDK is developed for Node.js, which makes it compatible with other runtimes through their compatibility layer.
The bugs in these compatibility layers may introduce issues in our SDK.

## Report issues

If you find any (undocumented) bugs when using the SDK, [submit a GitHub issue](https://github.com/AssemblyAI/assemblyai-node-sdk). We'll try to fix it or at least document the compatibility issue.
13 changes: 10 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"name": "assemblyai",
"version": "3.1.3",
"description": "The AssemblyAI Node.js SDK provides an easy-to-use interface for interacting with the AssemblyAI API, which supports async and real-time transcription, as well as the latest LeMUR models.",
"version": "4.0.0",
"description": "The AssemblyAI JavaScript SDK provides an easy-to-use interface for interacting with the AssemblyAI API, which supports async and real-time transcription, as well as the latest LeMUR models.",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"browser": "./dist/index.browser.js",
"default": "./dist/index.cjs"
},
"./package.json": "./package.json"
Expand All @@ -21,7 +22,7 @@
"url": "git+https://github.com/AssemblyAI/assemblyai-node-sdk.git"
},
"publishConfig": {
"tag": "latest",
"tag": "beta",
"access": "public",
"registry": "https://registry.npmjs.org/"
},
Expand Down Expand Up @@ -51,8 +52,12 @@
"src"
],
"devDependencies": {
"@rollup/plugin-alias": "^5.0.1",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-terser": "^0.4.4",
"@types/jest": "^29.5.5",
"@types/node": "^20.5.7",
"@types/websocket": "^1.0.8",
"@types/ws": "^8.5.5",
"@typescript-eslint/eslint-plugin": "^6.7.5",
"dotenv": "^16.3.1",
Expand All @@ -78,6 +83,8 @@
"typescript": "^5.2.2"
},
"dependencies": {
"@swimburger/isomorphic-streams": "^1.0.5",
"isomorphic-ws": "^5.0.0",
"ws": "^8.13.0"
}
}
73 changes: 64 additions & 9 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,81 @@
const pkg = require("./package.json");
const ts = require("rollup-plugin-typescript2");
const terser = require("@rollup/plugin-terser");
const alias = require("@rollup/plugin-alias");
const { nodeResolve } = require("@rollup/plugin-node-resolve");

const cjsFile = pkg.main;
const esmFile = pkg.module;
const browserFile = pkg.exports["."].browser;

const defaultPlugins = [
ts({
tsconfigOverride: { exclude: ["**/*.test.ts"] },
}),
];
const defaultConfig = {
plugins: defaultPlugins,
external: ["fs", "isomorphic-ws", "@swimburger/isomorphic-streams"],
input: "src/index.ts",
};

const browserConfig = {
...defaultConfig,
plugins: [
...defaultConfig.plugins,
alias({
entries: [{ find: "fs", replacement: "./src/browser/fs.ts" }],
}),
nodeResolve({ browser: true }),
],
external: [],
};

module.exports = [
{
plugins: [
ts({
tsconfigOverride: { exclude: ["**/*.test.ts"] },
}),
],
external: ["axios", "fs", "stream", "ws"],
input: "src/index.ts",
...defaultConfig,
output: [
{
file: pkg.main,
file: cjsFile,
format: "cjs",
exports: "named",
},
{
file: pkg.module,
file: esmFile,
format: "es",
exports: "named",
},
],
},
{
...browserConfig,
output: [
{
name: "assemblyai",
file: browserFile,
format: "esm",
},
],
},
{
...browserConfig,
output: [
{
name: "assemblyai",
file: "./dist/assemblyai.umd.js",
format: "umd",
},
],
},
{
...browserConfig,
plugins: [...browserConfig.plugins, terser()],
output: [
{
name: "assemblyai",
file: "./dist/assemblyai.umd.min.js",
format: "umd",
},
],
},
];
4 changes: 2 additions & 2 deletions scripts/generate-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ async function generateTypes(apiSpecPath: string, outputPath: string) {
let output = await openapiTS(localPath, {
alphabetize: true,
exportType: true,
transform(schemaObject, metadata) {
transform(schemaObject) {
if (
"x-fern-type" in schemaObject &&
schemaObject["x-fern-type"] === "datetime"
Expand All @@ -26,7 +26,7 @@ async function generateTypes(apiSpecPath: string, outputPath: string) {
output.indexOf("\n };\n responses", schemasPosition)
)
// Turn components["schemas"]["{TYPE_NAME}"] into TYPE_NAME
.replace(/components\[\"schemas\"]\[\"(\w*)\"\]/gm, "$1")
.replace(/components\["schemas"]\["(\w*)"\]/gm, "$1")
.split("\n")
// De-indent everything by 4
.map((l) => l.substring(4))
Expand Down
15 changes: 9 additions & 6 deletions scripts/kitchensink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
LemurBaseResponse,
PartialTranscript,
RealtimeTranscript,
CreateRealtimeServiceParams,
TranscribeParams,
} from "../src";

Expand All @@ -16,15 +17,17 @@ const client = new AssemblyAI({

(async function transcribeUsingRealtime() {
const useToken = false;
const serviceParams: any = {
sampleRate: 16_000,
wordBoost: ["gore", "climate"],
};
let token: undefined | string = undefined;
if (useToken) {
serviceParams.token = await client.realtime.createTemporaryToken({
token = await client.realtime.createTemporaryToken({
expires_in: 480,
});
}
const serviceParams: CreateRealtimeServiceParams = {
sampleRate: 16_000,
wordBoost: ["gore", "climate"],
token: token,
};
const rt = client.realtime.createService(serviceParams);

rt.on("open", ({ sessionId, expiresAt }) => {
Expand Down Expand Up @@ -282,7 +285,7 @@ const transcribeParams: TranscribeParams = {
);
console.log(page);
nextPageUrl = page.page_details.next_url;
} while (!!nextPageUrl);
} while (nextPageUrl);
})();

async function searchTranscript(transcript: Transcript) {
Expand Down
8 changes: 8 additions & 0 deletions src/browser/fs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
function throwError() {
throw new Error("Function is not supported in this environment.");
}

export const createReadStream = throwError;
export default {
createReadStream,
};
2 changes: 0 additions & 2 deletions src/services/files/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// import the fs module instead if specific named exports
// to keep the assemblyai module more compatible. Some fs polyfills don't include `createReadStream`.
import fs from "fs";
import { BaseService } from "../base";
import { UploadedFile, FileUploadParams, FileUploadData } from "../..";
Expand Down
Loading

0 comments on commit a784af9

Please sign in to comment.