npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@durable-streams/server-cloudflare

v0.1.1

Published

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

Readme

@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

| Path | What it is | | ---------------------- | -------------------------------------------------------------------------------------------------------------------- | | src/index.ts | Library entry: exports StreamObject, createStreamsHandler, types | | src/handler.ts | Worker router factory: per-path DO routing, CORS preflight, auth hook | | src/stream-object.ts | StreamObject DO: all protocol semantics (PUT/GET/POST/DELETE/HEAD, long-poll, SSE, producers, closure, TTL, forks) | | src/store.ts | SQLite access layer (meta / messages / producers tables) | | src/producer.ts | Pure idempotent-producer validation state machine | | src/json.ts | JSON-mode helpers (array flattening, fragment storage, array-wrapped reads) | | src/cursor.ts | CDN cache-collapsing cursor math | | template/index.ts | Worker 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.