@mhbdev/redis 0.2.0
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/CHANGELOG.md +9 -0
- package/LICENSE +21 -0
- package/README.md +173 -0
- package/dist/bullmq/adapter.d.ts +49 -0
- package/dist/bullmq/adapter.d.ts.map +1 -0
- package/dist/bullmq/adapter.js +56 -0
- package/dist/bullmq/adapter.js.map +1 -0
- package/dist/bullmq/index.d.ts +3 -0
- package/dist/bullmq/index.d.ts.map +1 -0
- package/dist/bullmq/index.js +2 -0
- package/dist/bullmq/index.js.map +1 -0
- package/dist/cache/cache.d.ts +31 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +78 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/index.d.ts +3 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +2 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/core/codec.d.ts +7 -0
- package/dist/core/codec.d.ts.map +1 -0
- package/dist/core/codec.js +24 -0
- package/dist/core/codec.js.map +1 -0
- package/dist/core/errors.d.ts +43 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +84 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/executor.d.ts +28 -0
- package/dist/core/executor.d.ts.map +1 -0
- package/dist/core/executor.js +27 -0
- package/dist/core/executor.js.map +1 -0
- package/dist/core/keys.d.ts +4 -0
- package/dist/core/keys.d.ts.map +1 -0
- package/dist/core/keys.js +15 -0
- package/dist/core/keys.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/ioredis/executor.d.ts +30 -0
- package/dist/ioredis/executor.d.ts.map +1 -0
- package/dist/ioredis/executor.js +52 -0
- package/dist/ioredis/executor.js.map +1 -0
- package/dist/ioredis/index.d.ts +5 -0
- package/dist/ioredis/index.d.ts.map +1 -0
- package/dist/ioredis/index.js +3 -0
- package/dist/ioredis/index.js.map +1 -0
- package/dist/ioredis/pubsub.d.ts +16 -0
- package/dist/ioredis/pubsub.d.ts.map +1 -0
- package/dist/ioredis/pubsub.js +42 -0
- package/dist/ioredis/pubsub.js.map +1 -0
- package/dist/locks/index.d.ts +3 -0
- package/dist/locks/index.d.ts.map +1 -0
- package/dist/locks/index.js +2 -0
- package/dist/locks/index.js.map +1 -0
- package/dist/locks/locks.d.ts +25 -0
- package/dist/locks/locks.d.ts.map +1 -0
- package/dist/locks/locks.js +77 -0
- package/dist/locks/locks.js.map +1 -0
- package/dist/node/client.d.ts +47 -0
- package/dist/node/client.d.ts.map +1 -0
- package/dist/node/client.js +155 -0
- package/dist/node/client.js.map +1 -0
- package/dist/node/errors.d.ts +3 -0
- package/dist/node/errors.d.ts.map +1 -0
- package/dist/node/errors.js +16 -0
- package/dist/node/errors.js.map +1 -0
- package/dist/node/index.d.ts +6 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +4 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/pool.d.ts +31 -0
- package/dist/node/pool.d.ts.map +1 -0
- package/dist/node/pool.js +131 -0
- package/dist/node/pool.js.map +1 -0
- package/dist/node/pubsub.d.ts +16 -0
- package/dist/node/pubsub.d.ts.map +1 -0
- package/dist/node/pubsub.js +41 -0
- package/dist/node/pubsub.js.map +1 -0
- package/dist/pubsub/contracts.d.ts +6 -0
- package/dist/pubsub/contracts.d.ts.map +1 -0
- package/dist/pubsub/contracts.js +2 -0
- package/dist/pubsub/contracts.js.map +1 -0
- package/dist/pubsub/index.d.ts +3 -0
- package/dist/pubsub/index.d.ts.map +1 -0
- package/dist/pubsub/index.js +2 -0
- package/dist/pubsub/index.js.map +1 -0
- package/dist/pubsub/pubsub.d.ts +15 -0
- package/dist/pubsub/pubsub.d.ts.map +1 -0
- package/dist/pubsub/pubsub.js +62 -0
- package/dist/pubsub/pubsub.js.map +1 -0
- package/dist/queue/index.d.ts +3 -0
- package/dist/queue/index.d.ts.map +1 -0
- package/dist/queue/index.js +2 -0
- package/dist/queue/index.js.map +1 -0
- package/dist/queue/queue.d.ts +78 -0
- package/dist/queue/queue.d.ts.map +1 -0
- package/dist/queue/queue.js +260 -0
- package/dist/queue/queue.js.map +1 -0
- package/dist/rate-limit/contracts.d.ts +93 -0
- package/dist/rate-limit/contracts.d.ts.map +1 -0
- package/dist/rate-limit/contracts.js +304 -0
- package/dist/rate-limit/contracts.js.map +1 -0
- package/dist/rate-limit/index.d.ts +3 -0
- package/dist/rate-limit/index.d.ts.map +1 -0
- package/dist/rate-limit/index.js +2 -0
- package/dist/rate-limit/index.js.map +1 -0
- package/dist/testing/fake-executor.d.ts +9 -0
- package/dist/testing/fake-executor.d.ts.map +1 -0
- package/dist/testing/fake-executor.js +15 -0
- package/dist/testing/fake-executor.js.map +1 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +2 -0
- package/dist/testing/index.js.map +1 -0
- package/docs/adapters.md +41 -0
- package/docs/architecture.md +41 -0
- package/docs/errors.md +27 -0
- package/docs/migration.md +21 -0
- package/docs/queues.md +13 -0
- package/docs/rate-limiting.md +23 -0
- package/docs/releasing.md +45 -0
- package/package.json +135 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type RedisCommand = readonly string[];
|
|
2
|
+
export type RedisCommandOptions = Readonly<{
|
|
3
|
+
signal?: AbortSignal;
|
|
4
|
+
}>;
|
|
5
|
+
export type RedisScriptOptions = Readonly<{
|
|
6
|
+
keys?: readonly string[];
|
|
7
|
+
arguments?: readonly string[];
|
|
8
|
+
}>;
|
|
9
|
+
export interface RedisExecutor {
|
|
10
|
+
execute<T = unknown>(command: RedisCommand, options?: RedisCommandOptions): Promise<T>;
|
|
11
|
+
eval<T = unknown>(script: string, options: RedisScriptOptions, request?: RedisCommandOptions): Promise<T>;
|
|
12
|
+
}
|
|
13
|
+
export interface RedisConnection extends RedisExecutor {
|
|
14
|
+
connect(): Promise<void>;
|
|
15
|
+
close(): Promise<void>;
|
|
16
|
+
ping(): Promise<void>;
|
|
17
|
+
readonly isReady: boolean;
|
|
18
|
+
}
|
|
19
|
+
export type RedisHooks = Readonly<{
|
|
20
|
+
onCommandStart?: (command: RedisCommand) => void;
|
|
21
|
+
onCommandEnd?: (command: RedisCommand, durationMs: number) => void;
|
|
22
|
+
onError?: (error: Error) => void;
|
|
23
|
+
onStateChange?: (state: RedisConnectionState) => void;
|
|
24
|
+
}>;
|
|
25
|
+
export type RedisConnectionState = "idle" | "connecting" | "ready" | "closed" | "error";
|
|
26
|
+
export declare function assertPositiveInteger(value: number, name: string): void;
|
|
27
|
+
export declare function withTimeout<T>(operation: (signal: AbortSignal) => Promise<T>, timeoutMs: number, message?: string): Promise<T>;
|
|
28
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/core/executor.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,GAAG,SAAS,MAAM,EAAE,CAAC;AAC7C,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IAAE,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,CAAC,CAAC;AACrE,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACzC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B,CAAC,CAAC;AAEH,MAAM,WAAW,aAAa;IAC7B,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACvF,IAAI,CAAC,CAAC,GAAG,OAAO,EACf,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,kBAAkB,EAC3B,OAAO,CAAC,EAAE,mBAAmB,GAC3B,OAAO,CAAC,CAAC,CAAC,CAAC;CACd;AAED,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACrD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IACjC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IACjD,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACnE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC;CACtD,CAAC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAExF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAIvE;AAED,wBAAsB,WAAW,CAAC,CAAC,EAClC,SAAS,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EAC9C,SAAS,EAAE,MAAM,EACjB,OAAO,SAA8B,GACnC,OAAO,CAAC,CAAC,CAAC,CAiBZ"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { RedisConfigurationError, RedisTimeoutError } from "./errors.js";
|
|
2
|
+
export function assertPositiveInteger(value, name) {
|
|
3
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
4
|
+
throw new RedisConfigurationError(`${name} must be a positive integer`);
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export async function withTimeout(operation, timeoutMs, message = "Redis operation timed out") {
|
|
8
|
+
assertPositiveInteger(timeoutMs, "Redis timeout");
|
|
9
|
+
const controller = new AbortController();
|
|
10
|
+
let timer;
|
|
11
|
+
try {
|
|
12
|
+
return await Promise.race([
|
|
13
|
+
operation(controller.signal),
|
|
14
|
+
new Promise((_, reject) => {
|
|
15
|
+
timer = setTimeout(() => {
|
|
16
|
+
controller.abort();
|
|
17
|
+
reject(new RedisTimeoutError(message));
|
|
18
|
+
}, timeoutMs);
|
|
19
|
+
}),
|
|
20
|
+
]);
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
if (timer)
|
|
24
|
+
clearTimeout(timer);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/core/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAkCzE,MAAM,UAAU,qBAAqB,CAAC,KAAa,EAAE,IAAY;IAChE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,uBAAuB,CAAC,GAAG,IAAI,6BAA6B,CAAC,CAAC;IACzE,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,SAA8C,EAC9C,SAAiB,EACjB,OAAO,GAAG,2BAA2B;IAErC,qBAAqB,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,IAAI,KAAgD,CAAC;IACrD,IAAI,CAAC;QACJ,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC;YACzB,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC;YAC5B,IAAI,OAAO,CAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;gBAC5B,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;oBACvB,UAAU,CAAC,KAAK,EAAE,CAAC;oBACnB,MAAM,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC;gBACxC,CAAC,EAAE,SAAS,CAAC,CAAC;YACf,CAAC,CAAC;SACF,CAAC,CAAC;IACJ,CAAC;YAAS,CAAC;QACV,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/core/keys.ts"],"names":[],"mappings":"AAIA,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKnE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAExE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAM/D"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { RedisConfigurationError } from "./errors.js";
|
|
2
|
+
const encoder = new TextEncoder();
|
|
3
|
+
export async function hashIdentifier(value) {
|
|
4
|
+
const digest = await crypto.subtle.digest("SHA-256", encoder.encode(value));
|
|
5
|
+
return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
6
|
+
}
|
|
7
|
+
export function namespacedKey(prefix, ...parts) {
|
|
8
|
+
return [prefix, ...parts].join(":");
|
|
9
|
+
}
|
|
10
|
+
export function assertKeyPart(value, name) {
|
|
11
|
+
if (!value.trim() || value.length > 256 || value.includes("\n")) {
|
|
12
|
+
throw new RedisConfigurationError(`${name} must be a non-empty value of at most 256 characters`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/core/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAElC,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAa;IACjD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5E,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAClD,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAClC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,GAAG,KAAe;IAC/D,OAAO,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,IAAY;IACxD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,uBAAuB,CAChC,GAAG,IAAI,sDAAsD,CAC7D,CAAC;IACH,CAAC;AACF,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export * from "./bullmq/index.js";
|
|
2
|
+
export * from "./cache/index.js";
|
|
3
|
+
export type { RedisCodec } from "./core/codec.js";
|
|
4
|
+
export { jsonCodec, stringCodec } from "./core/codec.js";
|
|
5
|
+
export type { RedisErrorCode } from "./core/errors.js";
|
|
6
|
+
export { asError, isRedisError, isRedisErrorCode, RedisClientStateError, RedisConfigurationError, RedisConnectionError, RedisError, RedisLockError, RedisProtocolError, RedisQueueError, RedisRequestAbortedError, RedisSerializationError, RedisTimeoutError, RedisUnavailableError, } from "./core/errors.js";
|
|
7
|
+
export type { RedisCommand, RedisCommandOptions, RedisConnection, RedisConnectionState, RedisExecutor, RedisHooks, RedisScriptOptions, } from "./core/executor.js";
|
|
8
|
+
export * from "./ioredis/index.js";
|
|
9
|
+
export * from "./locks/index.js";
|
|
10
|
+
export type { RedisClientOptions, RedisPoolOptions, } from "./node/index.js";
|
|
11
|
+
export { createRedisClient, createRedisPool, RedisClient, RedisPool, withRedisClient, withRedisPool, } from "./node/index.js";
|
|
12
|
+
export * from "./pubsub/index.js";
|
|
13
|
+
export * from "./queue/index.js";
|
|
14
|
+
export * from "./rate-limit/index.js";
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACzD,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EACN,OAAO,EACP,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,wBAAwB,EACxB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACX,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,UAAU,EACV,kBAAkB,GAClB,MAAM,oBAAoB,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,YAAY,EACX,kBAAkB,EAClB,gBAAgB,GAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,SAAS,EACT,eAAe,EACf,aAAa,GACb,MAAM,iBAAiB,CAAC;AACzB,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from "./bullmq/index.js";
|
|
2
|
+
export * from "./cache/index.js";
|
|
3
|
+
export { jsonCodec, stringCodec } from "./core/codec.js";
|
|
4
|
+
export { asError, isRedisError, isRedisErrorCode, RedisClientStateError, RedisConfigurationError, RedisConnectionError, RedisError, RedisLockError, RedisProtocolError, RedisQueueError, RedisRequestAbortedError, RedisSerializationError, RedisTimeoutError, RedisUnavailableError, } from "./core/errors.js";
|
|
5
|
+
export * from "./ioredis/index.js";
|
|
6
|
+
export * from "./locks/index.js";
|
|
7
|
+
export { createRedisClient, createRedisPool, RedisClient, RedisPool, withRedisClient, withRedisPool, } from "./node/index.js";
|
|
8
|
+
export * from "./pubsub/index.js";
|
|
9
|
+
export * from "./queue/index.js";
|
|
10
|
+
export * from "./rate-limit/index.js";
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,EACN,OAAO,EACP,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,wBAAwB,EACxB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,GACrB,MAAM,kBAAkB,CAAC;AAU1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AAKjC,OAAO,EACN,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,SAAS,EACT,eAAe,EACf,aAAa,GACb,MAAM,iBAAiB,CAAC;AACzB,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { RedisError } from "../core/errors.js";
|
|
2
|
+
import type { RedisCommand, RedisCommandOptions, RedisConnection, RedisScriptOptions } from "../core/executor.js";
|
|
3
|
+
export interface IoredisClientLike {
|
|
4
|
+
call(command: string, ...arguments_: string[]): Promise<unknown>;
|
|
5
|
+
eval(script: string, numberOfKeys: number, ...arguments_: string[]): Promise<unknown>;
|
|
6
|
+
ping(): Promise<unknown>;
|
|
7
|
+
quit?(): Promise<unknown>;
|
|
8
|
+
disconnect?(): void;
|
|
9
|
+
readonly status?: string;
|
|
10
|
+
}
|
|
11
|
+
export type IoredisExecutorOptions = Readonly<{
|
|
12
|
+
commandTimeoutMs?: number;
|
|
13
|
+
/** Map known ioredis/plugin error classes without inspecting error messages. */
|
|
14
|
+
normalizeError?: (error: unknown) => RedisError | undefined;
|
|
15
|
+
}>;
|
|
16
|
+
export declare class IoredisExecutor implements RedisConnection {
|
|
17
|
+
private readonly client;
|
|
18
|
+
private readonly options;
|
|
19
|
+
private readonly commandTimeoutMs;
|
|
20
|
+
constructor(client: IoredisClientLike, options?: IoredisExecutorOptions);
|
|
21
|
+
get isReady(): boolean;
|
|
22
|
+
connect(): Promise<void>;
|
|
23
|
+
execute<T = unknown>(command: RedisCommand, _options?: RedisCommandOptions): Promise<T>;
|
|
24
|
+
eval<T = unknown>(script: string, options: RedisScriptOptions, _options?: RedisCommandOptions): Promise<T>;
|
|
25
|
+
ping(): Promise<void>;
|
|
26
|
+
close(): Promise<void>;
|
|
27
|
+
private run;
|
|
28
|
+
}
|
|
29
|
+
export declare function createIoredisExecutor(client: IoredisClientLike, options?: IoredisExecutorOptions): IoredisExecutor;
|
|
30
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/ioredis/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,UAAU,EAEV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACX,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,MAAM,qBAAqB,CAAC;AAG7B,MAAM,WAAW,iBAAiB;IACjC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtF,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACzB,IAAI,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1B,UAAU,CAAC,IAAI,IAAI,CAAC;IACpB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC7C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gFAAgF;IAChF,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,UAAU,GAAG,SAAS,CAAC;CAC5D,CAAC,CAAC;AAEH,qBAAa,eAAgB,YAAW,eAAe;IAIrD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJzB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,YACkB,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,sBAA2B,EAGrD;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAI7B;IAEK,OAAO,CAAC,CAAC,GAAG,OAAO,EACxB,OAAO,EAAE,YAAY,EACrB,QAAQ,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,CAAC,CAAC,CAIZ;IAEK,IAAI,CAAC,CAAC,GAAG,OAAO,EACrB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,CAAC,CAAC,CAUZ;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAE1B;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3B;YAEa,GAAG;CAUjB;AAED,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,iBAAiB,EACzB,OAAO,CAAC,EAAE,sBAAsB,GAC9B,eAAe,CAEjB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { RedisClientStateError, RedisError, RedisUnavailableError, } from "../core/errors.js";
|
|
2
|
+
import { withTimeout } from "../core/executor.js";
|
|
3
|
+
export class IoredisExecutor {
|
|
4
|
+
client;
|
|
5
|
+
options;
|
|
6
|
+
commandTimeoutMs;
|
|
7
|
+
constructor(client, options = {}) {
|
|
8
|
+
this.client = client;
|
|
9
|
+
this.options = options;
|
|
10
|
+
this.commandTimeoutMs = options.commandTimeoutMs ?? 3_000;
|
|
11
|
+
}
|
|
12
|
+
get isReady() {
|
|
13
|
+
return this.client.status === undefined || this.client.status === "ready";
|
|
14
|
+
}
|
|
15
|
+
async connect() {
|
|
16
|
+
if (!this.isReady && this.client.status === "end")
|
|
17
|
+
throw new RedisClientStateError("The ioredis client has ended");
|
|
18
|
+
await this.run(() => this.client.ping());
|
|
19
|
+
}
|
|
20
|
+
async execute(command, _options) {
|
|
21
|
+
return this.run(() => this.client.call(command[0] ?? "", ...command.slice(1)));
|
|
22
|
+
}
|
|
23
|
+
async eval(script, options, _options) {
|
|
24
|
+
return this.run(() => this.client.eval(script, options.keys?.length ?? 0, ...(options.keys ?? []), ...(options.arguments ?? [])));
|
|
25
|
+
}
|
|
26
|
+
async ping() {
|
|
27
|
+
await this.run(() => this.client.ping());
|
|
28
|
+
}
|
|
29
|
+
async close() {
|
|
30
|
+
if (this.client.quit)
|
|
31
|
+
await this.client.quit();
|
|
32
|
+
else
|
|
33
|
+
this.client.disconnect?.();
|
|
34
|
+
}
|
|
35
|
+
async run(operation) {
|
|
36
|
+
try {
|
|
37
|
+
return await withTimeout(operation, this.commandTimeoutMs);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
const normalized = this.options.normalizeError?.(error);
|
|
41
|
+
if (normalized)
|
|
42
|
+
throw normalized;
|
|
43
|
+
if (error instanceof RedisError)
|
|
44
|
+
throw error;
|
|
45
|
+
throw new RedisUnavailableError(error);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function createIoredisExecutor(client, options) {
|
|
50
|
+
return new IoredisExecutor(client, options);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/ioredis/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,qBAAqB,EACrB,UAAU,EACV,qBAAqB,GACrB,MAAM,mBAAmB,CAAC;AAO3B,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAiBlD,MAAM,OAAO,eAAe;IAIT,MAAM;IACN,OAAO;IAJR,gBAAgB,CAAS;IAE1C,YACkB,MAAyB,EACzB,OAAO,GAA2B,EAAE;sBADpC,MAAM;uBACN,OAAO;QAExB,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,KAAK,CAAC;IAC3D,CAAC;IAED,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,OAAO,CAAC;IAC3E,CAAC;IAED,KAAK,CAAC,OAAO;QACZ,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,KAAK;YAChD,MAAM,IAAI,qBAAqB,CAAC,8BAA8B,CAAC,CAAC;QACjE,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,OAAO,CACZ,OAAqB,EACrB,QAA8B;QAE9B,OAAO,IAAI,CAAC,GAAG,CACd,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAe,CAC3E,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CACT,MAAc,EACd,OAA2B,EAC3B,QAA8B;QAE9B,OAAO,IAAI,CAAC,GAAG,CACd,GAAG,EAAE,CACJ,IAAI,CAAC,MAAM,CAAC,IAAI,CACf,MAAM,EACN,OAAO,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,EACzB,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,EACvB,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CACd,CAChB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACT,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,KAAK;QACV,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI;YAAE,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;;YAC1C,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;IACjC,CAAC;IAEO,KAAK,CAAC,GAAG,CAAI,SAA2B;QAC/C,IAAI,CAAC;YACJ,OAAO,MAAM,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC5D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC;YACxD,IAAI,UAAU;gBAAE,MAAM,UAAU,CAAC;YACjC,IAAI,KAAK,YAAY,UAAU;gBAAE,MAAM,KAAK,CAAC;YAC7C,MAAM,IAAI,qBAAqB,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC;IACF,CAAC;CACD;AAED,MAAM,UAAU,qBAAqB,CACpC,MAAyB,EACzB,OAAgC;IAEhC,OAAO,IAAI,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { IoredisClientLike, IoredisExecutorOptions } from "./executor.js";
|
|
2
|
+
export { createIoredisExecutor, IoredisExecutor } from "./executor.js";
|
|
3
|
+
export type { IoredisPubSubClientLike } from "./pubsub.js";
|
|
4
|
+
export { createIoredisPubSubTransport } from "./pubsub.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ioredis/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACvE,YAAY,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ioredis/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEvE,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RedisSubscriptionTransport } from "../pubsub/contracts.js";
|
|
2
|
+
export interface IoredisPubSubClientLike {
|
|
3
|
+
publish(channel: string, message: string): Promise<number>;
|
|
4
|
+
subscribe(channel: string): Promise<unknown>;
|
|
5
|
+
unsubscribe(channel: string): Promise<unknown>;
|
|
6
|
+
on(event: "message", listener: (channel: string, message: string) => void): this;
|
|
7
|
+
off?(event: "message", listener: (channel: string, message: string) => void): this;
|
|
8
|
+
duplicate?(): IoredisPubSubClientLike;
|
|
9
|
+
quit?(): Promise<unknown>;
|
|
10
|
+
disconnect?(): void;
|
|
11
|
+
}
|
|
12
|
+
export declare function createIoredisPubSubTransport(options: Readonly<{
|
|
13
|
+
publisher: IoredisPubSubClientLike;
|
|
14
|
+
subscriber?: IoredisPubSubClientLike;
|
|
15
|
+
}>): RedisSubscriptionTransport;
|
|
16
|
+
//# sourceMappingURL=pubsub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pubsub.d.ts","sourceRoot":"","sources":["../../src/ioredis/pubsub.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEzE,MAAM,WAAW,uBAAuB;IACvC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3D,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IACjF,GAAG,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IACnF,SAAS,CAAC,IAAI,uBAAuB,CAAC;IACtC,IAAI,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1B,UAAU,CAAC,IAAI,IAAI,CAAC;CACpB;AAED,wBAAgB,4BAA4B,CAC3C,OAAO,EAAE,QAAQ,CAAC;IACjB,SAAS,EAAE,uBAAuB,CAAC;IACnC,UAAU,CAAC,EAAE,uBAAuB,CAAC;CACrC,CAAC,GACA,0BAA0B,CAoC5B"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { RedisConfigurationError } from "../core/errors.js";
|
|
2
|
+
export function createIoredisPubSubTransport(options) {
|
|
3
|
+
const subscriber = options.subscriber ?? options.publisher.duplicate?.();
|
|
4
|
+
if (!subscriber)
|
|
5
|
+
throw new RedisConfigurationError("An ioredis subscriber or duplicate() method is required");
|
|
6
|
+
const listeners = new Map();
|
|
7
|
+
const onMessage = (channel, message) => {
|
|
8
|
+
for (const listener of listeners.get(channel) ?? [])
|
|
9
|
+
void listener(message);
|
|
10
|
+
};
|
|
11
|
+
subscriber.on("message", onMessage);
|
|
12
|
+
return {
|
|
13
|
+
publish: (channel, message) => options.publisher.publish(channel, message),
|
|
14
|
+
async subscribe(channel, handler) {
|
|
15
|
+
let channelListeners = listeners.get(channel);
|
|
16
|
+
if (!channelListeners) {
|
|
17
|
+
channelListeners = new Set();
|
|
18
|
+
listeners.set(channel, channelListeners);
|
|
19
|
+
await subscriber.subscribe(channel);
|
|
20
|
+
}
|
|
21
|
+
channelListeners.add(handler);
|
|
22
|
+
return async () => {
|
|
23
|
+
channelListeners?.delete(handler);
|
|
24
|
+
if (channelListeners?.size === 0) {
|
|
25
|
+
listeners.delete(channel);
|
|
26
|
+
await subscriber.unsubscribe(channel);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
async close() {
|
|
31
|
+
if (subscriber.quit)
|
|
32
|
+
await subscriber.quit();
|
|
33
|
+
else
|
|
34
|
+
subscriber.disconnect?.();
|
|
35
|
+
if (options.publisher.quit)
|
|
36
|
+
await options.publisher.quit();
|
|
37
|
+
else
|
|
38
|
+
options.publisher.disconnect?.();
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=pubsub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pubsub.js","sourceRoot":"","sources":["../../src/ioredis/pubsub.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAc5D,MAAM,UAAU,4BAA4B,CAC3C,OAGE;IAEF,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,CAAC;IACzE,IAAI,CAAC,UAAU;QACd,MAAM,IAAI,uBAAuB,CAChC,yDAAyD,CACzD,CAAC;IACH,MAAM,SAAS,GAAG,IAAI,GAAG,EAA0D,CAAC;IACpF,MAAM,SAAS,GAAG,CAAC,OAAe,EAAE,OAAe,EAAE,EAAE;QACtD,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE;YAAE,KAAK,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7E,CAAC,CAAC;IACF,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACpC,OAAO;QACN,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC;QAC1E,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO;YAC/B,IAAI,gBAAgB,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC9C,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACvB,gBAAgB,GAAG,IAAI,GAAG,EAAE,CAAC;gBAC7B,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;gBACzC,MAAM,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACrC,CAAC;YACD,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC9B,OAAO,KAAK,IAAI,EAAE;gBACjB,gBAAgB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;gBAClC,IAAI,gBAAgB,EAAE,IAAI,KAAK,CAAC,EAAE,CAAC;oBAClC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;oBAC1B,MAAM,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;gBACvC,CAAC;YACF,CAAC,CAAC;QACH,CAAC;QACD,KAAK,CAAC,KAAK;YACV,IAAI,UAAU,CAAC,IAAI;gBAAE,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;;gBACxC,UAAU,CAAC,UAAU,EAAE,EAAE,CAAC;YAC/B,IAAI,OAAO,CAAC,SAAS,CAAC,IAAI;gBAAE,MAAM,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;;gBACtD,OAAO,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,CAAC;QACvC,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/locks/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/locks/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { RedisExecutor } from "../core/executor.js";
|
|
2
|
+
export type RedisLockOptions = Readonly<{
|
|
3
|
+
redis: RedisExecutor;
|
|
4
|
+
prefix?: string;
|
|
5
|
+
defaultTtlMs?: number;
|
|
6
|
+
}>;
|
|
7
|
+
export interface RedisLockLease {
|
|
8
|
+
readonly key: string;
|
|
9
|
+
readonly token: string;
|
|
10
|
+
readonly expiresAt: number;
|
|
11
|
+
release(): Promise<boolean>;
|
|
12
|
+
extend(ttlMs: number): Promise<boolean>;
|
|
13
|
+
}
|
|
14
|
+
export declare class RedisLockManager {
|
|
15
|
+
private readonly options;
|
|
16
|
+
private readonly prefix;
|
|
17
|
+
private readonly defaultTtlMs;
|
|
18
|
+
constructor(options: RedisLockOptions);
|
|
19
|
+
acquire(name: string, ttlMs?: number): Promise<RedisLockLease | null>;
|
|
20
|
+
withLock<T>(name: string, operation: (lease: RedisLockLease) => Promise<T>, ttlMs?: number): Promise<T>;
|
|
21
|
+
}
|
|
22
|
+
export declare function createLockManager(options: RedisLockOptions): RedisLockManager;
|
|
23
|
+
/** A discoverable alias for applications that prefer Redis-prefixed factory names. */
|
|
24
|
+
export declare const createRedisLockManager: typeof createLockManager;
|
|
25
|
+
//# sourceMappingURL=locks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locks.d.ts","sourceRoot":"","sources":["../../src/locks/locks.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACvC,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC,CAAC;AAEH,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxC;AAED,qBAAa,gBAAgB;IAIhB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IAEtC,YAA6B,OAAO,EAAE,gBAAgB,EAGrD;IAEK,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAoB,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAyCrF;IAEK,QAAQ,CAAC,CAAC,EACf,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,EAChD,KAAK,SAAoB,GACvB,OAAO,CAAC,CAAC,CAAC,CAQZ;CACD;AAKD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CAE7E;AAED,sFAAsF;AACtF,eAAO,MAAM,sBAAsB,0BAAoB,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { RedisLockError } from "../core/errors.js";
|
|
3
|
+
export class RedisLockManager {
|
|
4
|
+
options;
|
|
5
|
+
prefix;
|
|
6
|
+
defaultTtlMs;
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.options = options;
|
|
9
|
+
this.prefix = options.prefix ?? "mhbdev:lock";
|
|
10
|
+
this.defaultTtlMs = options.defaultTtlMs ?? 30_000;
|
|
11
|
+
}
|
|
12
|
+
async acquire(name, ttlMs = this.defaultTtlMs) {
|
|
13
|
+
if (!name.trim())
|
|
14
|
+
throw new RedisLockError("Lock name is required");
|
|
15
|
+
if (!Number.isSafeInteger(ttlMs) || ttlMs <= 0)
|
|
16
|
+
throw new RedisLockError("Lock TTL must be positive");
|
|
17
|
+
const key = `${this.prefix}:${name}`;
|
|
18
|
+
const token = randomBytes(32).toString("hex");
|
|
19
|
+
const result = await this.options.redis.execute([
|
|
20
|
+
"SET",
|
|
21
|
+
key,
|
|
22
|
+
token,
|
|
23
|
+
"NX",
|
|
24
|
+
"PX",
|
|
25
|
+
String(ttlMs),
|
|
26
|
+
]);
|
|
27
|
+
if (result !== "OK")
|
|
28
|
+
return null;
|
|
29
|
+
const createdAt = Date.now();
|
|
30
|
+
let released = false;
|
|
31
|
+
return {
|
|
32
|
+
key,
|
|
33
|
+
token,
|
|
34
|
+
expiresAt: createdAt + ttlMs,
|
|
35
|
+
release: async () => {
|
|
36
|
+
if (released)
|
|
37
|
+
return false;
|
|
38
|
+
const result = await this.options.redis.eval(RELEASE_SCRIPT, {
|
|
39
|
+
keys: [key],
|
|
40
|
+
arguments: [token],
|
|
41
|
+
});
|
|
42
|
+
released = result === 1;
|
|
43
|
+
return released;
|
|
44
|
+
},
|
|
45
|
+
extend: async (nextTtlMs) => {
|
|
46
|
+
if (released)
|
|
47
|
+
return false;
|
|
48
|
+
if (!Number.isSafeInteger(nextTtlMs) || nextTtlMs <= 0)
|
|
49
|
+
throw new RedisLockError("Lock TTL must be positive");
|
|
50
|
+
const result = await this.options.redis.eval(EXTEND_SCRIPT, {
|
|
51
|
+
keys: [key],
|
|
52
|
+
arguments: [token, String(nextTtlMs)],
|
|
53
|
+
});
|
|
54
|
+
return result === 1;
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
async withLock(name, operation, ttlMs = this.defaultTtlMs) {
|
|
59
|
+
const lease = await this.acquire(name, ttlMs);
|
|
60
|
+
if (!lease)
|
|
61
|
+
throw new RedisLockError("Unable to acquire Redis lock");
|
|
62
|
+
try {
|
|
63
|
+
return await operation(lease);
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
await lease.release();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const RELEASE_SCRIPT = `if redis.call("GET", KEYS[1]) == ARGV[1] then return redis.call("DEL", KEYS[1]) else return 0 end`;
|
|
71
|
+
const EXTEND_SCRIPT = `if redis.call("GET", KEYS[1]) == ARGV[1] then return redis.call("PEXPIRE", KEYS[1], ARGV[2]) else return 0 end`;
|
|
72
|
+
export function createLockManager(options) {
|
|
73
|
+
return new RedisLockManager(options);
|
|
74
|
+
}
|
|
75
|
+
/** A discoverable alias for applications that prefer Redis-prefixed factory names. */
|
|
76
|
+
export const createRedisLockManager = createLockManager;
|
|
77
|
+
//# sourceMappingURL=locks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locks.js","sourceRoot":"","sources":["../../src/locks/locks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type RedisClientOptions as NodeRedisOptions, type RedisClientType } from "redis";
|
|
2
|
+
import { type RedisCommand, type RedisConnection, type RedisHooks, type RedisScriptOptions } from "../core/executor.js";
|
|
3
|
+
type EmptyModule = Record<never, never>;
|
|
4
|
+
export type NodeRedisClient = RedisClientType<EmptyModule, EmptyModule, EmptyModule, 3, EmptyModule>;
|
|
5
|
+
export type RedisClientOptions = Readonly<{
|
|
6
|
+
url: string;
|
|
7
|
+
connectTimeoutMs?: number;
|
|
8
|
+
commandTimeoutMs?: number;
|
|
9
|
+
maxReconnectAttempts?: number;
|
|
10
|
+
reconnectBaseDelayMs?: number;
|
|
11
|
+
reconnectMaxDelayMs?: number;
|
|
12
|
+
disableOfflineQueue?: boolean;
|
|
13
|
+
clientOptions?: Omit<NodeRedisOptions, "url" | "disableOfflineQueue">;
|
|
14
|
+
onError?: (error: Error) => void;
|
|
15
|
+
hooks?: RedisHooks;
|
|
16
|
+
}>;
|
|
17
|
+
export declare class RedisClient implements RedisConnection {
|
|
18
|
+
private client;
|
|
19
|
+
private readonly options;
|
|
20
|
+
private connecting;
|
|
21
|
+
private closing;
|
|
22
|
+
private closed;
|
|
23
|
+
constructor(options: RedisClientOptions);
|
|
24
|
+
get isReady(): boolean;
|
|
25
|
+
get isOpen(): boolean;
|
|
26
|
+
private createClient;
|
|
27
|
+
private replaceClient;
|
|
28
|
+
connect(): Promise<void>;
|
|
29
|
+
execute<T = unknown>(command: RedisCommand, options?: {
|
|
30
|
+
signal?: AbortSignal;
|
|
31
|
+
}): Promise<T>;
|
|
32
|
+
private sendCommand;
|
|
33
|
+
eval<T = unknown>(script: string, options: RedisScriptOptions, request?: {
|
|
34
|
+
signal?: AbortSignal;
|
|
35
|
+
}): Promise<T>;
|
|
36
|
+
ping(): Promise<void>;
|
|
37
|
+
raw(): NodeRedisClient;
|
|
38
|
+
close(): Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
export declare function createRedisClient(options: RedisClientOptions): RedisClient;
|
|
41
|
+
/**
|
|
42
|
+
* Creates, connects, and closes a managed client around one operation.
|
|
43
|
+
* This is useful for scripts, jobs, and request-scoped composition tests.
|
|
44
|
+
*/
|
|
45
|
+
export declare function withRedisClient<T>(options: RedisClientOptions, operation: (redis: RedisClient) => Promise<T>): Promise<T>;
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/node/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,kBAAkB,IAAI,gBAAgB,EAC3C,KAAK,eAAe,EACpB,MAAM,OAAO,CAAC;AAGf,OAAO,EAEN,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,kBAAkB,EAEvB,MAAM,qBAAqB,CAAC;AAG7B,KAAK,WAAW,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACxC,MAAM,MAAM,eAAe,GAAG,eAAe,CAC5C,WAAW,EACX,WAAW,EACX,WAAW,EACX,CAAC,EACD,WAAW,CACX,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,aAAa,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,qBAAqB,CAAC,CAAC;IACtE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,KAAK,CAAC,EAAE,UAAU,CAAC;CACnB,CAAC,CAAC;AAEH,qBAAa,WAAY,YAAW,eAAe;IAClD,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAmBrB;IACH,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,MAAM,CAAS;IAEvB,YAAY,OAAO,EAAE,kBAAkB,EActC;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,OAAO,CAAC,YAAY;IA4BpB,OAAO,CAAC,aAAa;IAMf,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CA0B7B;IAEK,OAAO,CAAC,CAAC,GAAG,OAAO,EACxB,OAAO,EAAE,YAAY,EACrB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GACpC,OAAO,CAAC,CAAC,CAAC,CAYZ;YAEa,WAAW;IAanB,IAAI,CAAC,CAAC,GAAG,OAAO,EACrB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,kBAAkB,EAC3B,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GACpC,OAAO,CAAC,CAAC,CAAC,CASZ;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAE1B;IAED,GAAG,IAAI,eAAe,CAErB;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAQ3B;CACD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAE1E;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,CAAC,EACtC,OAAO,EAAE,kBAAkB,EAC3B,SAAS,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAC3C,OAAO,CAAC,CAAC,CAAC,CAQZ"}
|