ai-resumable-stream 1.0.0 → 1.1.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.
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  </div>
11
11
 
12
- This library provides resumable streaming for UI message streams created by [`streamText()`](https://ai-sdk.dev/docs/reference/ai-sdk-core/stream-text) in the AI SDK. It uses Redis to persist stream data, allowing clients to resume interrupted streams or stop active streams from anywhere.
12
+ This library provides resumable streaming for UI message streams created by [`streamText()`](https://ai-sdk.dev/docs/reference/ai-sdk-core/stream-text) in the AI SDK. It uses Redis to store streaming chunks, allowing clients to resume interrupted streams or stop active streams from anywhere.
13
13
 
14
14
  **Why?**
15
15
 
@@ -63,7 +63,7 @@ sequenceDiagram
63
63
 
64
64
  ## Installation
65
65
 
66
- This library requires a [Redis](https://github.com/redis/node-redis) client.
66
+ This library requires [Redis](https://github.com/redis/node-redis).
67
67
 
68
68
  ```bash
69
69
  npm install ai-resumable-stream redis
@@ -71,7 +71,7 @@ npm install ai-resumable-stream redis
71
71
 
72
72
  ## Usage
73
73
 
74
- The library requires two Redis clients (pub/sub needs separate connections). The clients will connect automatically, if not already connected, but the library won't disconnect them afterwards. That means you can manage the connection lifecycle in your application and reuse clients across multiple streams.
74
+ The library requires two Redis clients (pub/sub needs separate connections). The clients will be connected automatically, if not already connected, but the library won't disconnect them afterwards. That means you can manage the connection lifecycle in your application and reuse clients across multiple streams.
75
75
 
76
76
  ```typescript
77
77
  import { createClient } from "redis";
@@ -0,0 +1,45 @@
1
+ import { AsyncIterableStream } from "ai-stream-utils/utils";
2
+ import { UIMessageChunk } from "ai";
3
+ import { createClient } from "redis";
4
+
5
+ //#region src/resumable-ui-message-stream.d.ts
6
+ type Redis = ReturnType<typeof createClient>;
7
+ type CreateResumableUIMessageStream = {
8
+ /**
9
+ * A unique identifier for the stream.
10
+ */
11
+ streamId: string;
12
+ /**
13
+ * A Redis client from the `redis` package.
14
+ * Checks if the client is already connected before attempting to connect.
15
+ */
16
+ subscriber: Redis;
17
+ /**
18
+ * A Redis client from the `redis` package.
19
+ * Checks if the client is already connected before attempting to connect.
20
+ */
21
+ publisher: Redis;
22
+ /**
23
+ * An optional AbortController that, when provided, allows the stream to be stopped by aborting the controller.
24
+ * If not provided, the stream will not be stoppable.
25
+ */
26
+ abortController?: AbortController;
27
+ /**
28
+ * A function that takes a promise and ensures that the current program stays alive
29
+ * until the promise is resolved.
30
+ *
31
+ * Omit if you are deploying to a server environment, where you don't have to worry about
32
+ * the function getting suspended.
33
+ */
34
+ waitUntil?: (promise: Promise<unknown>) => void;
35
+ };
36
+ /**
37
+ * Creates a resumable context for starting, resuming and stopping UI message streams.
38
+ */
39
+ declare function createResumableUIMessageStream(options: CreateResumableUIMessageStream): Promise<{
40
+ startStream: (stream: ReadableStream<UIMessageChunk>) => Promise<AsyncIterableStream<UIMessageChunk>>;
41
+ resumeStream: () => Promise<AsyncIterableStream<UIMessageChunk> | null>;
42
+ stopStream: () => Promise<void>;
43
+ }>;
44
+ //#endregion
45
+ export { createResumableUIMessageStream };
package/package.json CHANGED
@@ -1,71 +1,72 @@
1
1
  {
2
- "name": "ai-resumable-stream",
3
- "version": "1.0.0",
4
- "description": "AI SDK: resume and stop UI message streams",
5
- "keywords": [
6
- "ai",
7
- "ai-sdk",
8
- "redis",
9
- "resumable",
10
- "resumable-stream",
11
- "stream"
12
- ],
13
- "license": "MIT",
14
- "author": "Chris Cook",
15
- "repository": {
16
- "type": "git",
17
- "url": "git+https://github.com/zirkelc/ai-resumable-stream.git"
18
- },
19
- "files": [
20
- "dist"
21
- ],
22
- "type": "module",
23
- "exports": {
24
- ".": "./dist/index.mjs",
25
- "./package.json": "./package.json"
26
- },
27
- "scripts": {
28
- "prepublishOnly": "pnpm build",
29
- "build": "tsdown",
30
- "test": "vitest",
31
- "lint": "oxlint --fix",
32
- "lint:ci": "oxlint",
33
- "format": "oxfmt --write",
34
- "format:ci": "oxfmt --check",
35
- "prepare": "husky"
36
- },
37
- "dependencies": {
38
- "ai-stream-utils": "^1.5.0",
39
- "resumable-stream": "^2.2.10"
40
- },
41
- "devDependencies": {
42
- "@ai-sdk/provider": "^3.0.8",
43
- "@arethetypeswrong/cli": "^0.18.2",
44
- "@total-typescript/tsconfig": "^1.0.4",
45
- "@types/node": "^25.2.3",
46
- "@vitest/coverage-v8": "^4.0.18",
47
- "ai": "^6.0.79",
48
- "husky": "^9.1.7",
49
- "lint-staged": "^16.2.7",
50
- "oxfmt": "^0.31.0",
51
- "oxlint": "^1.46.0",
52
- "pkg-pr-new": "^0.0.63",
53
- "publint": "^0.3.17",
54
- "redis": "^5.10.0",
55
- "redis-memory-server": "^0.16.0",
56
- "tsdown": "^0.20.3",
57
- "tsx": "^4.21.0",
58
- "typescript": "^5.9.3",
59
- "vitest": "^4.0.18"
60
- },
61
- "lint-staged": {
62
- "*.{js,ts,tsx,jsx}": [
63
- "pnpm lint",
64
- "pnpm format"
65
- ],
66
- "*.{json,jsonc}": [
67
- "pnpm format"
68
- ]
69
- },
70
- "packageManager": "pnpm@10.0.0"
71
- }
2
+ "name": "ai-resumable-stream",
3
+ "version": "1.1.0",
4
+ "description": "AI SDK: resume and stop UI message streams",
5
+ "keywords": [
6
+ "ai",
7
+ "ai-sdk",
8
+ "redis",
9
+ "resumable",
10
+ "resumable-stream",
11
+ "stream"
12
+ ],
13
+ "license": "MIT",
14
+ "author": "Chris Cook",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/zirkelc/ai-resumable-stream.git"
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "type": "module",
23
+ "exports": {
24
+ ".": "./dist/index.mjs",
25
+ "./package.json": "./package.json"
26
+ },
27
+ "dependencies": {
28
+ "ai-stream-utils": "^1.6.0",
29
+ "resumable-stream": "^2.2.10"
30
+ },
31
+ "devDependencies": {
32
+ "@ai-sdk/provider": "^3.0.8",
33
+ "@arethetypeswrong/cli": "^0.18.2",
34
+ "@total-typescript/tsconfig": "^1.0.4",
35
+ "@types/node": "^25.2.3",
36
+ "@vitest/coverage-v8": "^4.0.18",
37
+ "ai": "^6.0.79",
38
+ "husky": "^9.1.7",
39
+ "lint-staged": "^16.2.7",
40
+ "oxfmt": "^0.31.0",
41
+ "oxlint": "^1.46.0",
42
+ "pkg-pr-new": "^0.0.63",
43
+ "publint": "^0.3.17",
44
+ "redis": "^5.10.0",
45
+ "redis-memory-server": "^0.16.0",
46
+ "tsdown": "^0.20.3",
47
+ "tsx": "^4.21.0",
48
+ "typescript": "^5.9.3",
49
+ "vitest": "^4.0.18"
50
+ },
51
+ "peerDependencies": {
52
+ "ai": "^6.0.0",
53
+ "redis": "^5.0.0"
54
+ },
55
+ "lint-staged": {
56
+ "*.{js,ts,tsx,jsx}": [
57
+ "pnpm lint",
58
+ "pnpm format"
59
+ ],
60
+ "*.{json,jsonc}": [
61
+ "pnpm format"
62
+ ]
63
+ },
64
+ "scripts": {
65
+ "build": "tsdown",
66
+ "test": "vitest",
67
+ "lint": "oxlint --fix",
68
+ "lint:ci": "oxlint",
69
+ "format": "oxfmt --write",
70
+ "format:ci": "oxfmt --check"
71
+ }
72
+ }