@durable-streams/server-cloudflare

中文文档
0.1.1发布于 2026/08/12Apache-2.0TypeScriptESM + CJS零依赖近 30 天下载 2.5万

Durable Streams protocol server on Cloudflare Workers + Durable Objects — export the StreamObject class and mount the handler in your own Worker

原始使用文档
文档目录7 节
  1. Usage
  2. Auth
  3. Conformance
  4. Layout
  5. Develop
  6. Design notes
  7. License

@durable-streams/server-cloudflare

A conformant Durable Streams protocol server on Cloudflare Workers + Durable Objects, in TypeScript — a library you mount in your own Worker.

Every stream is its own Durable Object instance (idFromName(streamPath)), giving the protocol's per-stream serialization and durability-before-ack for free via the DO input/output gates. All state lives in DO SQLite; long-poll waiters and SSE tails are held in the object; sliding TTLs use DO alarms; fork semantics (refcounted soft-delete, stitched reads, cascade GC) work across objects via DO-to-DO RPC.

Usage

pnpm add @durable-streams/server-cloudflare   # or npm install / yarn add

Your Worker entry:

// src/index.ts
import { createStreamsHandler } from "@durable-streams/server-cloudflare"

export { StreamObject } from "@durable-streams/server-cloudflare"

export default {
  fetch: createStreamsHandler(),
}

Your wrangler config — the DO binding must be named STREAMS (fork semantics do DO-to-DO RPC through it) and needs a SQLite migration:

// wrangler.jsonc
{
  "name": "my-streams",
  "main": "src/index.ts",
  "compatibility_date": "2025-06-01",
  "durable_objects": {
    "bindings": [{ "name": "STREAMS", "class_name": "StreamObject" }],
  },
  "migrations": [{ "tag": "v1", "new_sqlite_classes": ["StreamObject"] }],
}

The library's types reference Workers runtime types (DurableObjectNamespace, etc.) — generate them in your project with wrangler types.

Streams live at /<path> — the full request pathname is the stream path. If you mount the handler inside a larger Worker, route only the stream URLs to it (fork references between streams use these paths, so keep them stable). See the chat-cloudflare example for a TanStack Start app and this server sharing one Worker.

Auth

The protocol leaves auth to the implementation. By default, if an AUTH_TOKEN var/secret is set and non-empty, every request must carry Authorization: Bearer <token> (npx wrangler secret put AUTH_TOKEN); otherwise the server is open. Pass your own hook to replace that — return a Response to reject (CORS headers are added for you), undefined to allow:

export default {
  fetch: createStreamsHandler({
    auth: async (request, env) => {
      if (!(await isAuthorized(request, env))) {
        return new Response("Unauthorized", { status: 401 })
      }
      return undefined
    },
  }),
}

createStreamsHandler({ cors: false }) omits the permissive default CORS headers.

Conformance

Validated with @durable-streams/server-conformance-tests — the full suite, including fork semantics and idempotent-producer fencing: 326 passed, 0 failed (identical to the reference server; the 6 skips are the suite's own subscriptions-gated webhook tests, off by default — the experimental __ds subscription control plane is not implemented and returns 404).

pnpm conformance   # boots template/index.ts via wrangler dev (test/wrangler.jsonc) and runs the suite

Layout

PathWhat it is
src/index.tsLibrary entry: exports StreamObject, createStreamsHandler, types
src/handler.tsWorker router factory: per-path DO routing, CORS preflight, auth hook
src/stream-object.tsStreamObject DO: all protocol semantics (PUT/GET/POST/DELETE/HEAD, long-poll, SSE, producers, closure, TTL, forks)
src/store.tsSQLite access layer (meta / messages / producers tables)
src/producer.tsPure idempotent-producer validation state machine
src/json.tsJSON-mode helpers (array flattening, fragment storage, array-wrapped reads)
src/cursor.tsCDN cache-collapsing cursor math
template/index.tsWorker entry the conformance test boots (the usage snippet above, complete)
test/Conformance harness: boots wrangler dev and runs the shared suite

Develop

pnpm build       # emit dist/ (library build)
pnpm conformance # full conformance suite against a local wrangler dev instance
pnpm typecheck

Linting and formatting come from the repo root (pnpm lint, pnpm format at the monorepo root).

Design notes

  • Offsets use the reference format <readSeq>_<byteOffset> (16-digit zero-padded, lexicographically sortable); each message advances the byte offset by payload + 5 (frame overhead), matching the reference server byte-for-byte.
  • Concurrency: request bodies are read before any state is examined; every validate-then-write block is synchronous over the SQLite API, so the DO event loop makes it atomic — no locks needed.
  • TTL is enforced lazily on access (exact) and by a DO alarm (storage reclamation), so 1-second TTLs expire promptly.
  • Body cap is ~1.9MB per append (DO SQLite's 2MB value limit); larger appends get the protocol's 413.
  • Forks: creating a fork atomically validates + refcounts the source inside the source's DO (forkAcquire); deleting a referenced stream soft-deletes it (410 Gone), and the last fork release cascades a hard purge up the chain.

License

Apache-2.0. Protocol/validation logic is ported from the Apache-2.0 reference server (Durable Streams contributors) — see NOTICE and the per-file attribution headers.

版本与发布记录

@durable-streams/server-cloudflare 共发布 1 个版本,首次发布于 2026/08/12;过去 12 个月发布了 1 个版本。

版本发布日期距今
0.1.1latest2026/08/123 个月前

关于 @durable-streams/server-cloudflare 的常见问题

@durable-streams/server-cloudflare 是什么?

Durable Streams protocol server on Cloudflare Workers + Durable Objects — export the StreamObject class and mount the handler in your own Worker

如何安装 @durable-streams/server-cloudflare?

在项目目录运行 npm install @durable-streams/server-cloudflare,或使用 pnpm add / yarn add / bun add。

@durable-streams/server-cloudflare 支持 TypeScript 吗?

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

@durable-streams/server-cloudflare 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@durable-streams/server-cloudflare 可以商用吗?

@durable-streams/server-cloudflare 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@durable-streams/server-cloudflare 的下载量有多少?

根据 npm 官方下载统计,@durable-streams/server-cloudflare 在 2026/10/13 – 2026/11/11 这 30 天内被下载 25,176 次,日均约 839 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@durable-streams/server-cloudflare 还在维护吗?

最新版本 0.1.1 发布于 2026/08/12(3 个月前);至今共发布 1 个版本,其中过去 12 个月发布了 1 个;首次发布于 2026/08/12。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。