@convex-dev/persistent-text-streaming

中文文档
0.3.5发布于 2026/10/23Apache-2.0TypeScriptES Module零依赖近 30 天下载 23.4万

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

中文使用文档
文档目录6 节
  1. 预先要求: Convex
  2. 安装
  3. 使用量
  4. 斯韦尔特 (β)
  5. 设计哲学
  6. 背景情况

Convex 组件:持续文本流

npm version

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

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

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

example-animation

预先要求: Convex

你需要一个现有的 Convex 项目来使用组件。 Convex 是一个主机 后端平台,包括数据库、无服务器功能和多一个吨 可以学习 这里。 。 。 .

运行 npm create convex 或遵循其中任何一条 快速启动 来设置一个.

安装

见 example/ 一个工作演示.

  1. 安装持续文本流组件 :
npm install @convex-dev/persistent-text-streaming
  1. 创建一个 convex.config.ts 文档中 应用程序 convex/ 通过调用文件夹并安装组件 use数字 :
// 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数字 :

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数字 :

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();
    }
  }),
});

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

// 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,与 setupConvex 在父组件中调用。 反应输入以 获取器。 见 example-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 流线聊天。 。 。 .

版本与发布记录

@convex-dev/persistent-text-streaming 共发布 14 个版本,首次发布于 2025/03/01;过去 12 个月发布了 6 个版本。

版本发布日期距今
0.3.5latest2026/10/2318 天前
0.3.42026/10/101 个月前
0.3.32026/06/254 个月前
0.3.22026/04/087 个月前
0.3.12026/04/087 个月前
0.3.02025/11/1311 个月前

其他发布通道:alpha → 0.2.3-alpha.0。

关于 @convex-dev/persistent-text-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 和提交记录判断。