# @convex-dev/persistent-text-streaming 中文文档

规范地址：https://npmcn.com/package/%40convex-dev/persistent-text-streaming/

版本：0\.3\.5
npm 元数据更新时间：2026-10-22T23:45:58.831Z
中文译文更新时间：2026-11-10T17:47:56.499Z
软件包许可：Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40convex-dev/persistent-text-streaming
原文对照：https://npmcn.com/package/%40convex-dev/persistent-text-streaming/?lang=original
项目主页：https://github.com/get-convex/persistent-text-streaming#readme
源码仓库：https://github.com/get-convex/persistent-text-streaming

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：151 kB，61 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：0 个
- peer 依赖：react ~18\.3\.1 \|\| ^19\.0\.0，convex ^1\.32\.0，svelte ^5\.0\.0，react-dom ~18\.3\.1 \|\| ^19\.0\.0，convex-svelte \>=0\.0\.12 \<0\.16\.0
- 首次发布：2025-03-01T02:20:35.250Z
- 最新版本发布：2026-10-22T23:45:58.619Z
- 近 30 天下载量：233849（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：14（近 12 个月 6 个）

## 中文简介

从 LLMs 和其他来源向客户端传输持久文本的 Convex 组件.

## 安装

```sh
npm install @convex-dev/persistent-text-streaming
```

也可以使用：`pnpm add @convex-dev/persistent-text-streaming`、`yarn add @convex-dev/persistent-text-streaming`、`bun add @convex-dev/persistent-text-streaming`

## README

# Convex 组件:持续文本流

[![npm version](https://badge.fury.io/js/@convex-dev%2Fpersistent-text-streaming.svg)](https://badge.fury.io/js/@convex-dev%2Fpersistent-text-streaming)

这个 Convex 组件允许持续文本流 。 它提供了反应 hTTP 动作中流出文本的钩子, 同时存储数据 在数据库中。 此持久性允许文本在 流尾或由其他用户.

最常见的使用案例是AI聊天应用程序. 示例应用程序( 发现于 页:1 `example` 目录)只是一个简单的聊天应用程序,可以显示用途 构成部分.

这就是你最后的结果! 左侧浏览器窗口正在流出聊天内容 对象到客户端,右浏览器窗口则订阅到聊天正文 通过数据库查询。 消息只在句子数据库中更新 边框,而 HTTP 流会随其来时发出符号 :

![example-animation](https://npmcn.com/package/%40convex-dev/persistent-text-streaming/anim.gif)

## 预先要求: Convex

你需要一个现有的 Convex 项目来使用组件。 Convex 是一个主机 后端平台,包括数据库、无服务器功能和多一个吨 可以学习 [这里](https://docs.convex.dev/get-started)。 。 。 .

运行 `npm create convex` 或遵循其中任何一条 [快速启动](https://docs.convex.dev/home) 来设置一个.

## 安装

见 [`example/`](https://npmcn.com/package/%40convex-dev/persistent-text-streaming/example/convex/) 一个工作演示.

1.  安装持续文本流组件 :

```bash
npm install @convex-dev/persistent-text-streaming
```

2.  创建一个 [`convex.config.ts`](https://npmcn.com/package/%40convex-dev/persistent-text-streaming/example/convex/convex.config.ts) 文档中 应用程序 `convex/` 通过调用文件夹并安装组件 `use`数字 :

```ts
// convex/convex.config.ts
import { defineApp } from "convex/server";
import persistentTextStreaming from "@convex-dev/persistent-text-streaming/convex.config.js";

const app = defineApp();
app.use(persistentTextStreaming);
export default app;
```

## 使用量

以下是如何使用组件的简单例子:

单位 `convex/chat.ts`数字 :

```ts
const persistentTextStreaming = new PersistentTextStreaming(
  components.persistentTextStreaming,
);

// Create a stream using the component and store the id in the database with
// our chat message.
export const createChat = mutation({
  args: {
    prompt: v.string(),
  },
  handler: async (ctx, args) => {
    const streamId = await persistentTextStreaming.createStream(ctx);
    const chatId = await ctx.db.insert("chats", {
      title: "...",
      prompt: args.prompt,
      stream: streamId,
    });
    return chatId;
  },
});

// Create a query that returns the chat body.
export const getChatBody = query({
  args: {
    streamId: StreamIdValidator,
  },
  handler: async (ctx, args) => {
    return await persistentTextStreaming.getStreamBody(
      ctx,
      args.streamId as StreamId,
    );
  },
});

// Create an HTTP action that generates chunks of the chat body
// and uses the component to stream them to the client and save them to the database.
export const streamChat = httpAction(async (ctx, request) => {
  const body = (await request.json()) as { streamId: string };
  const generateChat = async (ctx, request, streamId, chunkAppender) => {
    await chunkAppender("Hi there!");
    await chunkAppender("How are you?");
    await chunkAppender("Pretend I'm an AI or something!");
  };

  const response = await persistentTextStreaming.stream(
    ctx,
    request,
    body.streamId as StreamId,
    generateChat,
  );

  // Set CORS headers appropriately.
  response.headers.set("Access-Control-Allow-Origin", "*");
  response.headers.set("Vary", "Origin");
  return response;
});
```

您需要在您的后端显示此 HTTP 端点, 所以 `convex/http.ts`数字 :

```ts
http.route({
  path: "/chat-stream",
  method: "POST",
  handler: streamChat,
});

// Handle CORS preflight requests so browsers will allow the POST above when
// your app is served from a different origin than your Convex deployment.
http.route({
  path: "/chat-stream",
  method: "OPTIONS",
  handler: httpAction(async (_, request) => {
    const headers = request.headers;
    if (
      headers.get("Origin") !== null &&
      headers.get("Access-Control-Request-Method") !== null &&
      headers.get("Access-Control-Request-Headers") !== null
    ) {
      return new Response(null, {
        headers: new Headers({
          "Access-Control-Allow-Origin": "*",
          "Access-Control-Allow-Methods": "POST",
          "Access-Control-Allow-Headers": "Content-Type, Digest, Authorization",
          "Access-Control-Max-Age": "86400",
        }),
      });
    } else {
      return new Response();
    }
  }),
});
```

最后,在您的应用程序中,你可以创建聊天,他们通过 最佳流程和/或数据库查询 :

```ts
// chat-input.tsx, maybe?
const createChat = useMutation(api.chat.createChat);
const formSubmit = async (e: React.FormEvent) => {
  e.preventDefault();
  const chatId = await createChat({
    prompt: inputValue,
  });
};

// chat-message.tsx, maybe?
import { useStream } from "@convex-dev/persistent-text-streaming/react";

// ...

// In our component:
const { text, status } = useStream(
  api.chat.getChatBody, // The query to call for the full stream body
  new URL(`${convexSiteUrl}/chat-stream`), // The HTTP endpoint for streaming
  driven, // True if this browser session created this chat and should generate the stream
  chat.streamId as StreamId, // The streamId from the chat database record
);
```

### 斯韦尔特 (β)

Svelte 5捆绑由社区支持并用β. 他们需要 `svelte` 财务报告和审定财务报表 [`convex-svelte`](https://github.com/get-convex/convex-svelte),与 `setupConvex` 在父组件中调用。 反应输入以 获取器。 见 [`example-svelte/`](https://npmcn.com/package/%40convex-dev/persistent-text-streaming/example-svelte/) 为了聊天的应用.

```svelte
<script lang="ts">
  import { useStream } from "@convex-dev/persistent-text-streaming/svelte";

  let { chat, driven }: { chat: Doc<"chats">; driven: boolean } = $props();

  const stream = useStream(
    api.chat.getChatBody,
    new URL(`${convexSiteUrl}/chat-stream`),
    () => driven,
    () => chat.streamId as StreamId,
    // Optional, read when a stream starts:
    // () => ({ authToken, headers }),
  );
</script>

<p>{stream.text}</p>
```

`stream.text` 财务报告和审定财务报表 `stream.status` 随着溪流的进展而更新。 HTTP 软件 请求仅在浏览器中开始,在服务器侧渲染时从未开始.

## 设计哲学

此组件平衡了 HTTP 流与数据库的持久性,以尝试 尽量扩大两者的好处。 要了解为什么这种平衡是有利的, 让我们孤立地检查每一个方法.

-   **仅流出 HTTP**: 如果您的应用程序 _仅限_ 使用 HTTP 流线,然后 提出请求的原始浏览器将具有出色的高性能 流经. 但如果HTTP连接丢失, 如果浏览器 窗口被重新装入,如果其他用户想要查看相同的聊天,或者这个用户 等会再谈,不可能的 这个 对话只是暂时的,因为它从未被存储在服务器上.
    
-   **只有数据库持久性**: 如果您的应用程序 _仅限_ 使用数据库持久性, 谈话会随你便. 此外,Convex的订阅将确保聊天消息更新 随着新文本块的生成。 然而,有一些缺点: 整个聊天机构需要 怨恨每次改变,这是很多 将冗余带宽推入数据库并覆盖到所有 websockets 连接客户端. 第二,你需要做一个艰难的权衡 互动和效率。 如果你把每一个小块写到 数据库中,这将变得相当缓慢和昂贵。 但是,如果你批量起来 插入,比如说,段落, 然后用户体验会感觉糟糕.
    

这个部分结合了两个世界中最好的. 制作的原始浏览器 请求仍将有出色的高性能流畅的经验。 不过 聊天机构也存储在数据库中,因此可以被 客户端即使在流完成之后,或者其他用户等等.

## 背景情况

这一构成部分主要基于Stack员额 [AI 与 HTTP 流线聊天](https://stack.convex.dev/ai-chat-with-http-streaming)。 。 。 .

## 常见问题

### @convex-dev/persistent-text-streaming 是什么？

从 LLMs 和其他来源向客户端传输持久文本的 Convex 组件\.

### 如何安装 @convex-dev/persistent-text-streaming？

在项目目录运行 npm install @convex-dev/persistent-text-streaming，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：convex（^1\.32\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @convex-dev/persistent-text-streaming 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @convex-dev/persistent-text-streaming 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @convex-dev/persistent-text-streaming 可以商用吗？

@convex-dev/persistent-text-streaming 使用 Apache-2\.0 许可。宽松许可：允许商业使用、修改和再分发，并附带明确的专利授权；分发时需保留许可与 NOTICE 文件，修改过的文件要注明改动。以上为概括，不构成法律意见，请以许可原文为准。

### @convex-dev/persistent-text-streaming 的下载量有多少？

根据 npm 官方下载统计，@convex-dev/persistent-text-streaming 在 2026/10/11 – 2026/11/09 这 30 天内被下载 233,849 次，日均约 7,795 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @convex-dev/persistent-text-streaming 还在维护吗？

最新版本 0\.3\.5 发布于 2026/10/23（18 天前）；至今共发布 14 个版本，其中过去 12 个月发布了 6 个；首次发布于 2025/03/01。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

