Skip to content

feat: add prefix method to publisher, rate limiter, and lock adapters - #2332

Merged
dinwwwh merged 4 commits into
mainfrom
claude/adapter-prefix-methods-f0aab7
Oct 24, 2026
Merged

dinwwwh merged 4 commits into
mainfrom
claude/adapter-prefix-methods-f0aab7

Conversation

@dinwwwh

@dinwwwh dinwwwh commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

Publisher, rate limiter, and lock adapters that take a prefix option now also have a prefix() method. It returns a new adapter with the given prefix appended that shares the original's client, so scoping per request or tenant is cheap: limiter.prefix(`tenant:${id}:`).

Changes

  • Available on the Redis, Upstash, Bun Redis, and Cloudflare adapters. Memory adapters don't have it, since a new instance wouldn't share their state.
  • Publishers created by prefix() on RedisPublisher and BunRedisPublisher reuse the original subscriber connection and add no extra error listener to it, so creating one per request doesn't leak.
  • Each adapter example in the docs shows a prefix() call.

Notes

  • The protected prefix field of BaseRedisLocker, BaseRedisRateLimiter, and BaseRedisPublisher is now keyPrefix/eventPrefix, to make room for the method. Only custom subclasses that read it are affected.

Testing

  • Each adapter has a test that a prefixed instance shares keys, counters, or events with the original.
  • Redis and Cloudflare suites pass locally. Upstash and Bun tests were not run locally (no credentials / Bun runtime), so CI is their first run.

Adapters with a `prefix` option now have a `prefix()` method that returns a
new adapter with the given prefix appended, sharing the same client, so it is
cheap to create per request or tenant. Memory adapters do not have it.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
orpc 4064a06 Commit Preview URL

Branch Preview URL
Oct 24 2026, 01:58 PM

@pkg-pr-new

pkg-pr-new Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
More templates

@orpc/ai-sdk

npm i https://pkg.pr.new/@orpc/ai-sdk@2332

@orpc/arktype

npm i https://pkg.pr.new/@orpc/arktype@2332

@orpc/bun

npm i https://pkg.pr.new/@orpc/bun@2332

@orpc/client

npm i https://pkg.pr.new/@orpc/client@2332

@orpc/cloudflare

npm i https://pkg.pr.new/@orpc/cloudflare@2332

@orpc/contract

npm i https://pkg.pr.new/@orpc/contract@2332

@orpc/effect

npm i https://pkg.pr.new/@orpc/effect@2332

@orpc/evlog

npm i https://pkg.pr.new/@orpc/evlog@2332

@orpc/hibernation

npm i https://pkg.pr.new/@orpc/hibernation@2332

@orpc/json-schema

npm i https://pkg.pr.new/@orpc/json-schema@2332

@orpc/experimental-lock

npm i https://pkg.pr.new/@orpc/experimental-lock@2332

@orpc/mcp

npm i https://pkg.pr.new/@orpc/mcp@2332

@orpc/msw

npm i https://pkg.pr.new/@orpc/msw@2332

@orpc/nest

npm i https://pkg.pr.new/@orpc/nest@2332

@orpc/next

npm i https://pkg.pr.new/@orpc/next@2332

@orpc/node

npm i https://pkg.pr.new/@orpc/node@2332

@orpc/openapi

npm i https://pkg.pr.new/@orpc/openapi@2332

@orpc/opentelemetry

npm i https://pkg.pr.new/@orpc/opentelemetry@2332

@orpc/pinia-colada

npm i https://pkg.pr.new/@orpc/pinia-colada@2332

@orpc/pino

npm i https://pkg.pr.new/@orpc/pino@2332

@orpc/publisher

npm i https://pkg.pr.new/@orpc/publisher@2332

@orpc/ratelimit

npm i https://pkg.pr.new/@orpc/ratelimit@2332

@orpc/server

npm i https://pkg.pr.new/@orpc/server@2332

@orpc/shared

npm i https://pkg.pr.new/@orpc/shared@2332

@orpc/swr

npm i https://pkg.pr.new/@orpc/swr@2332

@orpc/tanstack-query

npm i https://pkg.pr.new/@orpc/tanstack-query@2332

@orpc/trpc

npm i https://pkg.pr.new/@orpc/trpc@2332

@orpc/valibot

npm i https://pkg.pr.new/@orpc/valibot@2332

@orpc/zod

npm i https://pkg.pr.new/@orpc/zod@2332

commit: 4064a06

@codecov

codecov Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codspeed

codspeed Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

1 warning

⚠️ 5 benchmarks are dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

✅ 28 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing claude/adapter-prefix-methods-f0aab7 (4064a06) with main (5dc334e)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

Upstash integration tests are skipped in CI without credentials, so test prefix() against a fake client instead.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — one minor docs wording nit inline.

Reviewed changes

  • prefix() on every Redis/Upstash/Bun/Cloudflare adapter — publisher, rate limiter, and lock adapters gain a prefix(prefix) method returning a new instance with the prefix appended while sharing the original's client / binding / namespace.
  • Shared subscriber for prefixed publishers — RedisPublisher now keeps a single error listener per subscriber via a module-level subscriberOnErrors WeakMap, and BunRedisPublisher hands its once-wrapped getSubscriber and onErrors to prefixed instances, so per-request prefix() calls don't accumulate listeners.
  • Protected field rename — BaseRedisLocker/BaseRedisRateLimiter's prefix becomes keyPrefix and BaseRedisPublisher's becomes eventPrefix (Cloudflare adapters likewise); documented in the PR body as breaking for custom subclasses, which is fine on the 2.0.0-beta.x line.
  • Tests and docs — each adapter has a "shares ... with ... created by prefix" test, plus a prefix() example per adapter in the helper docs.

I verified the diff end-to-end and independently traced the shared-subscriber refactor (listener count, error fan-out, and unsubscribe scope) without finding a defect; tsc -b for publisher/lock/ratelimit/bun, the root tsc --noEmit, and eslint on the changed files all pass. The Redis/Upstash/Bun suites are credential/runtime-gated here, so CI is their first run.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Comment thread apps/content/docs/helpers/lock.mdx Outdated

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No new issues in the follow-up commit — the earlier docs-wording suggestion is still open (the docs weren't touched here).

Reviewed changes (since 76bde9d)

  • Upstash prefix() tests moved from integration to unit tests (c989404) — the three credential-gated Upstash integration tests for prefix() are replaced with always-run unit tests that use a mocked client and assert the appended key/channel (app:tenant:key, tenant:event) and client reuse, so CI now exercises prefix() for Upstash without credentials.
  • Verified locally: the three new tests pass (3 passed | 36 skipped), eslint is clean on the changed files, and the root tsc --noEmit passes.

Pullfrog  | Fix it ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@dinwwwh
dinwwwh merged commit 4c76597 into main Oct 24, 2026
12 checks passed
dinwwwh added a commit that referenced this pull request Oct 25, 2026
The Upstash publisher tests have been failing since #2332 renamed the
protected `prefix` field to `eventPrefix`. The tests still read
`prefix`, which now returns the new `prefix()` method, so they looked up
the wrong Redis keys and channels.

## Fixes
- "supports custom serializers and custom prefixes" finds its stream key
again.
- "does not crash if teardown runs after internal maps were already
pruned" finds its subscription and cleans it up, so the suite-wide
`afterAll` cleanup check passes again.

## Testing
- Publisher, rate limiter, and lock Upstash suites pass locally against
a real Upstash server (39/39).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant