@orpc/bun 2.0.0-beta.35 → 2.0.0-beta.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -20
- package/dist/index.d.mts +20 -37
- package/dist/index.d.ts +20 -37
- package/dist/index.mjs +21 -84
- package/package.json +9 -7
package/README.md
CHANGED
|
@@ -43,29 +43,30 @@ You can read the documentation [here](https://orpc.dev).
|
|
|
43
43
|
|
|
44
44
|
**Built-in features**
|
|
45
45
|
|
|
46
|
-
| Package
|
|
47
|
-
|
|
|
48
|
-
| [@orpc/publisher](https://www.npmjs.com/package/@orpc/publisher)
|
|
49
|
-
| [@orpc/ratelimit](https://www.npmjs.com/package/@orpc/ratelimit)
|
|
50
|
-
| [@orpc/
|
|
51
|
-
| [@orpc/
|
|
46
|
+
| Package | Purpose | Docs |
|
|
47
|
+
| -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
|
|
48
|
+
| [@orpc/publisher](https://www.npmjs.com/package/@orpc/publisher) | Pub/Sub with memory, Redis, and Upstash adapters. | [Publisher](https://orpc.dev/docs/helpers/publisher) |
|
|
49
|
+
| [@orpc/ratelimit](https://www.npmjs.com/package/@orpc/ratelimit) | Rate limiting with memory, Redis, and Upstash adapters. | [Rate Limit](https://orpc.dev/docs/helpers/ratelimit) |
|
|
50
|
+
| [@orpc/experimental-lock](https://www.npmjs.com/package/@orpc/experimental-lock) | Locking with memory, Redis, and Upstash adapters. | [Lock](https://orpc.dev/docs/helpers/lock) |
|
|
51
|
+
| [@orpc/hibernation](https://www.npmjs.com/package/@orpc/hibernation) | Leverage Hibernation APIs like [Cloudflare's Hibernation WebSocket](https://developers.cloudflare.com/durable-objects/best-practices/websockets/#durable-objects-hibernation-websocket-api). | [Hibernation](https://orpc.dev/docs/integrations/hibernation) |
|
|
52
|
+
| [@orpc/json-schema](https://www.npmjs.com/package/@orpc/json-schema) | Smart coercion for OpenAPI requests. | [Smart Coercion](https://orpc.dev/docs/plugins/smart-coercion) |
|
|
52
53
|
|
|
53
54
|
**Framework & ecosystem integrations**
|
|
54
55
|
|
|
55
|
-
| Package | Purpose | Docs
|
|
56
|
-
| ------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- |
|
|
57
|
-
| [@orpc/next](https://www.npmjs.com/package/@orpc/next) | Integrate with [Next.js Server Functions](https://nextjs.org/docs/app/getting-started/mutating-data). | [Next.js](https://orpc.dev/docs/integrations/next)
|
|
58
|
-
| [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk) | Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools. | [AI SDK](https://orpc.dev/docs/integrations/ai-sdk)
|
|
59
|
-
| [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query) | Integrate with [TanStack Query](https://tanstack.com/query/latest). | [TanStack Query](https://orpc.dev/docs/integrations/tanstack-query)
|
|
60
|
-
| [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada) | Integrate with [Pinia Colada](https://pinia-colada.esm.dev/). | [Pinia Colada](https://orpc.dev/docs/integrations/pinia-colada)
|
|
61
|
-
| [@orpc/swr](https://www.npmjs.com/package/@orpc/swr) | Integrate with [SWR](https://swr.vercel.app/). | [SWR](https://orpc.dev/docs/integrations/swr)
|
|
62
|
-
| [@orpc/experimental-msw](https://www.npmjs.com/package/@orpc/experimental-msw) | Mock procedures with [Mock Service Worker](https://mswjs.io/). | [MSW](https://orpc.dev/docs/integrations/msw)
|
|
63
|
-
| [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect) | Integrate with [Effect](https://effect.website/). | [Effect](https://orpc.dev/docs/integrations/effect)
|
|
64
|
-
| [@orpc/nest](https://www.npmjs.com/package/@orpc/nest) | Implement your contract with [NestJS](https://nestjs.com/). | [NestJS](https://orpc.dev/docs/integrations/nest)
|
|
65
|
-
| [@orpc/node](https://www.npmjs.com/package/@orpc/node) | [Node.js](https://nodejs.org/) plugins for static file serving and large uploads. | [Static File](https://orpc.dev/docs/plugins/static-file), [Tmp File Upload](https://orpc.dev/docs/plugins/tmp-file-upload), [Batch Response Compression](https://orpc.dev/docs/plugins/batch-response-compression)
|
|
66
|
-
| [@orpc/bun](https://www.npmjs.com/package/@orpc/bun) | Adapters for [Bun's Redis](https://bun.sh/). | [Publisher](https://orpc.dev/docs/helpers/publisher), [Rate Limit](https://orpc.dev/docs/helpers/ratelimit)
|
|
67
|
-
| [@orpc/cloudflare](https://www.npmjs.com/package/@orpc/cloudflare) | Adapters for [Cloudflare Workers](https://developers.cloudflare.com/workers/). | [Publisher](https://orpc.dev/docs/helpers/publisher), [Rate Limit](https://orpc.dev/docs/helpers/ratelimit), [Traces](https://orpc.dev/docs/integrations/cloudflare-traces)
|
|
68
|
-
| [@orpc/trpc](https://www.npmjs.com/package/@orpc/trpc) | Reuse existing [tRPC](https://trpc.io/) routers within oRPC. | [tRPC](https://orpc.dev/docs/integrations/trpc)
|
|
56
|
+
| Package | Purpose | Docs |
|
|
57
|
+
| ------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
58
|
+
| [@orpc/next](https://www.npmjs.com/package/@orpc/next) | Integrate with [Next.js Server Functions](https://nextjs.org/docs/app/getting-started/mutating-data). | [Next.js](https://orpc.dev/docs/integrations/next) |
|
|
59
|
+
| [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk) | Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools. | [AI SDK](https://orpc.dev/docs/integrations/ai-sdk) |
|
|
60
|
+
| [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query) | Integrate with [TanStack Query](https://tanstack.com/query/latest). | [TanStack Query](https://orpc.dev/docs/integrations/tanstack-query) |
|
|
61
|
+
| [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada) | Integrate with [Pinia Colada](https://pinia-colada.esm.dev/). | [Pinia Colada](https://orpc.dev/docs/integrations/pinia-colada) |
|
|
62
|
+
| [@orpc/swr](https://www.npmjs.com/package/@orpc/swr) | Integrate with [SWR](https://swr.vercel.app/). | [SWR](https://orpc.dev/docs/integrations/swr) |
|
|
63
|
+
| [@orpc/experimental-msw](https://www.npmjs.com/package/@orpc/experimental-msw) | Mock procedures with [Mock Service Worker](https://mswjs.io/). | [MSW](https://orpc.dev/docs/integrations/msw) |
|
|
64
|
+
| [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect) | Integrate with [Effect](https://effect.website/). | [Effect](https://orpc.dev/docs/integrations/effect) |
|
|
65
|
+
| [@orpc/nest](https://www.npmjs.com/package/@orpc/nest) | Implement your contract with [NestJS](https://nestjs.com/). | [NestJS](https://orpc.dev/docs/integrations/nest) |
|
|
66
|
+
| [@orpc/node](https://www.npmjs.com/package/@orpc/node) | [Node.js](https://nodejs.org/) plugins for static file serving and large uploads. | [Static File](https://orpc.dev/docs/plugins/static-file), [Tmp File Upload](https://orpc.dev/docs/plugins/tmp-file-upload), [Batch Response Compression](https://orpc.dev/docs/plugins/batch-response-compression) |
|
|
67
|
+
| [@orpc/bun](https://www.npmjs.com/package/@orpc/bun) | Adapters for [Bun's Redis](https://bun.sh/). | [Publisher](https://orpc.dev/docs/helpers/publisher), [Rate Limit](https://orpc.dev/docs/helpers/ratelimit), [Lock](https://orpc.dev/docs/helpers/lock) |
|
|
68
|
+
| [@orpc/cloudflare](https://www.npmjs.com/package/@orpc/cloudflare) | Adapters for [Cloudflare Workers](https://developers.cloudflare.com/workers/). | [Publisher](https://orpc.dev/docs/helpers/publisher), [Rate Limit](https://orpc.dev/docs/helpers/ratelimit), [Lock](https://orpc.dev/docs/helpers/lock), [Traces](https://orpc.dev/docs/integrations/cloudflare-traces) |
|
|
69
|
+
| [@orpc/trpc](https://www.npmjs.com/package/@orpc/trpc) | Reuse existing [tRPC](https://trpc.io/) routers within oRPC. | [tRPC](https://orpc.dev/docs/integrations/trpc) |
|
|
69
70
|
|
|
70
71
|
**Observability**
|
|
71
72
|
|
|
@@ -91,6 +92,14 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
|
|
|
91
92
|
</tr>
|
|
92
93
|
</table>
|
|
93
94
|
|
|
95
|
+
### Special Sponsors
|
|
96
|
+
|
|
97
|
+
<table>
|
|
98
|
+
<tr>
|
|
99
|
+
<td align="center"><a href="http://twitter.com/rauchg?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Guillermo Rauch"><img src="https://avatars.githubusercontent.com/u/13041?u=1ee8d111657cdd02ff6d253df00978d17ee6d722&v=4" width="279" alt="Guillermo Rauch"/><br />Guillermo Rauch</a></td>
|
|
100
|
+
</tr>
|
|
101
|
+
</table>
|
|
102
|
+
|
|
94
103
|
### Organization Sponsors
|
|
95
104
|
|
|
96
105
|
<table>
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
|
+
import { BaseRedisLocker, BaseRedisLockerOptions } from '@orpc/experimental-lock/base-redis';
|
|
2
|
+
import { RedisClient } from 'bun';
|
|
1
3
|
import { BaseRedisPublisher, BaseRedisPublisherOptions, RedisStreamTrimOptions, RedisStreamEntry } from '@orpc/publisher/base-redis';
|
|
2
4
|
import { Promisable } from '@orpc/shared';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
+
import { BaseRedisRateLimiter, BaseRedisRateLimiterOptions } from '@orpc/ratelimit/base-redis';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Locker adapter for Bun's built-in Redis client. Acquires locks with `SET NX PX`
|
|
9
|
+
* and releases them atomically with a Lua script. It shares locks with `RedisLocker`.
|
|
10
|
+
*
|
|
11
|
+
* @see {@link https://orpc.dev/docs/helpers/lock#adapters | Lock Helpers - Adapters}
|
|
12
|
+
*/
|
|
13
|
+
declare class experimental_BunRedisLocker extends BaseRedisLocker {
|
|
14
|
+
private readonly redis;
|
|
15
|
+
constructor(redis: RedisClient, options: BaseRedisLockerOptions);
|
|
16
|
+
protected acquire(key: string, token: string, ttl: number): Promise<boolean>;
|
|
17
|
+
protected evalScript(script: string, keys: string[], args: string[]): Promise<unknown>;
|
|
18
|
+
}
|
|
5
19
|
|
|
6
20
|
interface BunRedisPublisherOptions extends BaseRedisPublisherOptions {
|
|
7
21
|
/**
|
|
@@ -29,28 +43,7 @@ declare class BunRedisPublisher<T extends Record<string, object>> extends BaseRe
|
|
|
29
43
|
protected readStreamEntries(key: string, lastId: string): Promise<RedisStreamEntry[]>;
|
|
30
44
|
}
|
|
31
45
|
|
|
32
|
-
interface BunRedisRateLimiterOptions {
|
|
33
|
-
/**
|
|
34
|
-
* The prefix to use for Redis keys.
|
|
35
|
-
*
|
|
36
|
-
* @default ''
|
|
37
|
-
*/
|
|
38
|
-
prefix?: string;
|
|
39
|
-
/**
|
|
40
|
-
* Maximum number of requests allowed within the window.
|
|
41
|
-
*/
|
|
42
|
-
maxRequests: number;
|
|
43
|
-
/**
|
|
44
|
-
* The duration of the fixed window in milliseconds.
|
|
45
|
-
*/
|
|
46
|
-
window: number;
|
|
47
|
-
/**
|
|
48
|
-
* Block until the request may pass or timeout is reached.
|
|
49
|
-
*/
|
|
50
|
-
blockingUntilReady?: {
|
|
51
|
-
enabled: boolean;
|
|
52
|
-
timeout: number;
|
|
53
|
-
};
|
|
46
|
+
interface BunRedisRateLimiterOptions extends BaseRedisRateLimiterOptions {
|
|
54
47
|
}
|
|
55
48
|
/**
|
|
56
49
|
* Rate limiter adapter for Bun's built-in Redis client. Enforces a fixed-window
|
|
@@ -58,21 +51,11 @@ interface BunRedisRateLimiterOptions {
|
|
|
58
51
|
*
|
|
59
52
|
* @see {@link https://orpc.dev/docs/helpers/ratelimit#adapters | Rate Limit Helpers - Adapters}
|
|
60
53
|
*/
|
|
61
|
-
declare class BunRedisRateLimiter
|
|
54
|
+
declare class BunRedisRateLimiter extends BaseRedisRateLimiter {
|
|
62
55
|
private readonly redis;
|
|
63
|
-
private readonly prefix;
|
|
64
|
-
private readonly maxRequests;
|
|
65
|
-
private readonly window;
|
|
66
|
-
private readonly blockingUntilReady;
|
|
67
|
-
private scriptSha;
|
|
68
56
|
constructor(redis: RedisClient, options: BunRedisRateLimiterOptions);
|
|
69
|
-
|
|
70
|
-
private checkLimit;
|
|
71
|
-
private blockUntilReady;
|
|
72
|
-
private executeScript;
|
|
73
|
-
private evalSha;
|
|
74
|
-
private resolveWeight;
|
|
57
|
+
protected evalScript(script: string, keys: string[], args: string[]): Promise<unknown>;
|
|
75
58
|
}
|
|
76
59
|
|
|
77
|
-
export { BunRedisPublisher, BunRedisRateLimiter };
|
|
60
|
+
export { BunRedisPublisher, BunRedisRateLimiter, experimental_BunRedisLocker };
|
|
78
61
|
export type { BunRedisPublisherOptions, BunRedisRateLimiterOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
|
+
import { BaseRedisLocker, BaseRedisLockerOptions } from '@orpc/experimental-lock/base-redis';
|
|
2
|
+
import { RedisClient } from 'bun';
|
|
1
3
|
import { BaseRedisPublisher, BaseRedisPublisherOptions, RedisStreamTrimOptions, RedisStreamEntry } from '@orpc/publisher/base-redis';
|
|
2
4
|
import { Promisable } from '@orpc/shared';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
+
import { BaseRedisRateLimiter, BaseRedisRateLimiterOptions } from '@orpc/ratelimit/base-redis';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Locker adapter for Bun's built-in Redis client. Acquires locks with `SET NX PX`
|
|
9
|
+
* and releases them atomically with a Lua script. It shares locks with `RedisLocker`.
|
|
10
|
+
*
|
|
11
|
+
* @see {@link https://orpc.dev/docs/helpers/lock#adapters | Lock Helpers - Adapters}
|
|
12
|
+
*/
|
|
13
|
+
declare class experimental_BunRedisLocker extends BaseRedisLocker {
|
|
14
|
+
private readonly redis;
|
|
15
|
+
constructor(redis: RedisClient, options: BaseRedisLockerOptions);
|
|
16
|
+
protected acquire(key: string, token: string, ttl: number): Promise<boolean>;
|
|
17
|
+
protected evalScript(script: string, keys: string[], args: string[]): Promise<unknown>;
|
|
18
|
+
}
|
|
5
19
|
|
|
6
20
|
interface BunRedisPublisherOptions extends BaseRedisPublisherOptions {
|
|
7
21
|
/**
|
|
@@ -29,28 +43,7 @@ declare class BunRedisPublisher<T extends Record<string, object>> extends BaseRe
|
|
|
29
43
|
protected readStreamEntries(key: string, lastId: string): Promise<RedisStreamEntry[]>;
|
|
30
44
|
}
|
|
31
45
|
|
|
32
|
-
interface BunRedisRateLimiterOptions {
|
|
33
|
-
/**
|
|
34
|
-
* The prefix to use for Redis keys.
|
|
35
|
-
*
|
|
36
|
-
* @default ''
|
|
37
|
-
*/
|
|
38
|
-
prefix?: string;
|
|
39
|
-
/**
|
|
40
|
-
* Maximum number of requests allowed within the window.
|
|
41
|
-
*/
|
|
42
|
-
maxRequests: number;
|
|
43
|
-
/**
|
|
44
|
-
* The duration of the fixed window in milliseconds.
|
|
45
|
-
*/
|
|
46
|
-
window: number;
|
|
47
|
-
/**
|
|
48
|
-
* Block until the request may pass or timeout is reached.
|
|
49
|
-
*/
|
|
50
|
-
blockingUntilReady?: {
|
|
51
|
-
enabled: boolean;
|
|
52
|
-
timeout: number;
|
|
53
|
-
};
|
|
46
|
+
interface BunRedisRateLimiterOptions extends BaseRedisRateLimiterOptions {
|
|
54
47
|
}
|
|
55
48
|
/**
|
|
56
49
|
* Rate limiter adapter for Bun's built-in Redis client. Enforces a fixed-window
|
|
@@ -58,21 +51,11 @@ interface BunRedisRateLimiterOptions {
|
|
|
58
51
|
*
|
|
59
52
|
* @see {@link https://orpc.dev/docs/helpers/ratelimit#adapters | Rate Limit Helpers - Adapters}
|
|
60
53
|
*/
|
|
61
|
-
declare class BunRedisRateLimiter
|
|
54
|
+
declare class BunRedisRateLimiter extends BaseRedisRateLimiter {
|
|
62
55
|
private readonly redis;
|
|
63
|
-
private readonly prefix;
|
|
64
|
-
private readonly maxRequests;
|
|
65
|
-
private readonly window;
|
|
66
|
-
private readonly blockingUntilReady;
|
|
67
|
-
private scriptSha;
|
|
68
56
|
constructor(redis: RedisClient, options: BunRedisRateLimiterOptions);
|
|
69
|
-
|
|
70
|
-
private checkLimit;
|
|
71
|
-
private blockUntilReady;
|
|
72
|
-
private executeScript;
|
|
73
|
-
private evalSha;
|
|
74
|
-
private resolveWeight;
|
|
57
|
+
protected evalScript(script: string, keys: string[], args: string[]): Promise<unknown>;
|
|
75
58
|
}
|
|
76
59
|
|
|
77
|
-
export { BunRedisPublisher, BunRedisRateLimiter };
|
|
60
|
+
export { BunRedisPublisher, BunRedisRateLimiter, experimental_BunRedisLocker };
|
|
78
61
|
export type { BunRedisPublisherOptions, BunRedisRateLimiterOptions };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
|
+
import { BaseRedisLocker } from '@orpc/experimental-lock/base-redis';
|
|
1
2
|
import { BaseRedisPublisher } from '@orpc/publisher/base-redis';
|
|
2
|
-
import {
|
|
3
|
+
import { BaseRedisRateLimiter } from '@orpc/ratelimit/base-redis';
|
|
4
|
+
|
|
5
|
+
class experimental_BunRedisLocker extends BaseRedisLocker {
|
|
6
|
+
constructor(redis, options) {
|
|
7
|
+
super(options);
|
|
8
|
+
this.redis = redis;
|
|
9
|
+
}
|
|
10
|
+
async acquire(key, token, ttl) {
|
|
11
|
+
const result = await this.redis.send("SET", [key, token, "NX", "PX", String(ttl)]);
|
|
12
|
+
return result === "OK";
|
|
13
|
+
}
|
|
14
|
+
async evalScript(script, keys, args) {
|
|
15
|
+
return await this.redis.send("EVAL", [script, String(keys.length), ...keys, ...args]);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
3
18
|
|
|
4
19
|
class BunRedisPublisher extends BaseRedisPublisher {
|
|
5
20
|
constructor(redis, { subscriber, ...options } = {}) {
|
|
@@ -37,92 +52,14 @@ class BunRedisPublisher extends BaseRedisPublisher {
|
|
|
37
52
|
}
|
|
38
53
|
}
|
|
39
54
|
|
|
40
|
-
|
|
41
|
-
local key = KEYS[1]
|
|
42
|
-
local weight = tonumber(ARGV[1])
|
|
43
|
-
local window = tonumber(ARGV[2])
|
|
44
|
-
|
|
45
|
-
local current = redis.call('INCRBY', key, weight)
|
|
46
|
-
|
|
47
|
-
if current == weight then
|
|
48
|
-
redis.call('PEXPIRE', key, window)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
local ttl = redis.call('PTTL', key)
|
|
52
|
-
|
|
53
|
-
return { current, ttl }
|
|
54
|
-
`;
|
|
55
|
-
class BunRedisRateLimiter {
|
|
56
|
-
redis;
|
|
57
|
-
prefix;
|
|
58
|
-
maxRequests;
|
|
59
|
-
window;
|
|
60
|
-
blockingUntilReady;
|
|
61
|
-
scriptSha;
|
|
55
|
+
class BunRedisRateLimiter extends BaseRedisRateLimiter {
|
|
62
56
|
constructor(redis, options) {
|
|
57
|
+
super(options);
|
|
63
58
|
this.redis = redis;
|
|
64
|
-
this.prefix = options.prefix ?? "";
|
|
65
|
-
this.maxRequests = options.maxRequests;
|
|
66
|
-
this.window = options.window;
|
|
67
|
-
this.blockingUntilReady = options.blockingUntilReady;
|
|
68
|
-
}
|
|
69
|
-
async limit(key, options) {
|
|
70
|
-
key = `${this.prefix}${key}`;
|
|
71
|
-
const weight = this.resolveWeight(options);
|
|
72
|
-
return this.blockingUntilReady?.enabled ? this.blockUntilReady(key, this.blockingUntilReady.timeout, weight) : this.checkLimit(key, weight);
|
|
73
|
-
}
|
|
74
|
-
async checkLimit(key, weight) {
|
|
75
|
-
const [used, ttl] = await this.executeScript(key, weight);
|
|
76
|
-
return {
|
|
77
|
-
success: used <= this.maxRequests,
|
|
78
|
-
limit: this.maxRequests,
|
|
79
|
-
remaining: Math.max(0, this.maxRequests - used),
|
|
80
|
-
reset: Date.now() + ttl
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
async blockUntilReady(key, timeoutMs, weight) {
|
|
84
|
-
const deadlineAtMs = Date.now() + timeoutMs;
|
|
85
|
-
while (true) {
|
|
86
|
-
const result = await this.checkLimit(key, weight);
|
|
87
|
-
if (result.success || result.reset > deadlineAtMs) {
|
|
88
|
-
return result;
|
|
89
|
-
}
|
|
90
|
-
await sleep(result.reset - Date.now());
|
|
91
|
-
}
|
|
92
59
|
}
|
|
93
|
-
async
|
|
94
|
-
|
|
95
|
-
return await this.evalSha(key, weight);
|
|
96
|
-
} catch (error) {
|
|
97
|
-
if (error instanceof Error && error.message.startsWith("NOSCRIPT")) {
|
|
98
|
-
this.scriptSha = void 0;
|
|
99
|
-
return await this.evalSha(key, weight);
|
|
100
|
-
}
|
|
101
|
-
throw error;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
async evalSha(key, weight) {
|
|
105
|
-
this.scriptSha ??= await this.redis.send("SCRIPT", [
|
|
106
|
-
"LOAD",
|
|
107
|
-
FIXED_WINDOW_RATELIMIT_SCRIPT
|
|
108
|
-
]);
|
|
109
|
-
return await this.redis.send("EVALSHA", [
|
|
110
|
-
this.scriptSha,
|
|
111
|
-
"1",
|
|
112
|
-
key,
|
|
113
|
-
String(weight),
|
|
114
|
-
String(this.window)
|
|
115
|
-
]);
|
|
116
|
-
}
|
|
117
|
-
resolveWeight(options) {
|
|
118
|
-
const weight = options?.weight ?? 1;
|
|
119
|
-
if (!Number.isInteger(weight) || weight <= 0) {
|
|
120
|
-
throw new TypeError(
|
|
121
|
-
"Rate limit weight must be an integer greater than 0"
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
return weight;
|
|
60
|
+
async evalScript(script, keys, args) {
|
|
61
|
+
return await this.redis.send("EVAL", [script, String(keys.length), ...keys, ...args]);
|
|
125
62
|
}
|
|
126
63
|
}
|
|
127
64
|
|
|
128
|
-
export { BunRedisPublisher, BunRedisRateLimiter };
|
|
65
|
+
export { BunRedisPublisher, BunRedisRateLimiter, experimental_BunRedisLocker };
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orpc/bun",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
5
|
-
"description": "Bun integration for oRPC: Redis-backed pub/sub
|
|
4
|
+
"version": "2.0.0-beta.36",
|
|
5
|
+
"description": "Bun integration for oRPC: Redis-backed pub/sub, rate limiting, and locking using Bun's built-in Redis client",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"funding": [
|
|
8
8
|
"https://github.com/sponsors/dinwwwh",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"redis",
|
|
21
21
|
"pubsub",
|
|
22
22
|
"ratelimit",
|
|
23
|
+
"lock",
|
|
23
24
|
"typescript"
|
|
24
25
|
],
|
|
25
26
|
"sideEffects": false,
|
|
@@ -35,11 +36,12 @@
|
|
|
35
36
|
"dist"
|
|
36
37
|
],
|
|
37
38
|
"dependencies": {
|
|
38
|
-
"@orpc/client": "2.0.0-beta.
|
|
39
|
-
"@orpc/
|
|
40
|
-
"@orpc/
|
|
41
|
-
"@orpc/
|
|
42
|
-
"@orpc/
|
|
39
|
+
"@orpc/client": "2.0.0-beta.36",
|
|
40
|
+
"@orpc/experimental-lock": "2.0.0-beta.36",
|
|
41
|
+
"@orpc/publisher": "2.0.0-beta.36",
|
|
42
|
+
"@orpc/ratelimit": "2.0.0-beta.36",
|
|
43
|
+
"@orpc/server": "2.0.0-beta.36",
|
|
44
|
+
"@orpc/shared": "2.0.0-beta.36",
|
|
43
45
|
"@standard-server/core": "~0.9.0"
|
|
44
46
|
},
|
|
45
47
|
"devDependencies": {
|