ioredis-toolkit 0.0.1

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.
Files changed (74) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +645 -0
  3. package/dist/cache.d.ts +298 -0
  4. package/dist/cache.js +606 -0
  5. package/dist/client.d.ts +177 -0
  6. package/dist/client.js +958 -0
  7. package/dist/cluster-slot.d.ts +4 -0
  8. package/dist/cluster-slot.js +31 -0
  9. package/dist/cluster.d.ts +79 -0
  10. package/dist/cluster.js +156 -0
  11. package/dist/errors.d.ts +30 -0
  12. package/dist/errors.js +63 -0
  13. package/dist/health.d.ts +39 -0
  14. package/dist/health.js +106 -0
  15. package/dist/index.d.ts +51 -0
  16. package/dist/index.js +44 -0
  17. package/dist/lock.d.ts +215 -0
  18. package/dist/lock.js +385 -0
  19. package/dist/logger.d.ts +12 -0
  20. package/dist/logger.js +40 -0
  21. package/dist/pubsub.d.ts +171 -0
  22. package/dist/pubsub.js +285 -0
  23. package/dist/ratelimiter.d.ts +162 -0
  24. package/dist/ratelimiter.js +289 -0
  25. package/dist/session/index.d.ts +23 -0
  26. package/dist/session/index.js +16 -0
  27. package/dist/session/revocation-store.d.ts +171 -0
  28. package/dist/session/revocation-store.js +310 -0
  29. package/dist/session/scripts/cleanup-index.lua +21 -0
  30. package/dist/session/scripts/conditional-update-encrypted.lua +60 -0
  31. package/dist/session/scripts/conditional-update.lua +63 -0
  32. package/dist/session/scripts/create.lua +68 -0
  33. package/dist/session/scripts/delete-by-user.lua +29 -0
  34. package/dist/session/scripts/delete.lua +15 -0
  35. package/dist/session/scripts/enforce-limit.lua +38 -0
  36. package/dist/session/scripts/revoke.lua +61 -0
  37. package/dist/session/scripts/rotate-encrypted.lua +107 -0
  38. package/dist/session/scripts/rotate.lua +119 -0
  39. package/dist/session/scripts/touch-encrypted.lua +89 -0
  40. package/dist/session/scripts/touch.lua +72 -0
  41. package/dist/session/scripts/validate.lua +90 -0
  42. package/dist/session/session-circuit-breaker.d.ts +42 -0
  43. package/dist/session/session-circuit-breaker.js +129 -0
  44. package/dist/session/session-config.d.ts +335 -0
  45. package/dist/session/session-config.js +162 -0
  46. package/dist/session/session-cookie.d.ts +72 -0
  47. package/dist/session/session-cookie.js +101 -0
  48. package/dist/session/session-encryption.d.ts +87 -0
  49. package/dist/session/session-encryption.js +139 -0
  50. package/dist/session/session-errors.d.ts +85 -0
  51. package/dist/session/session-errors.js +145 -0
  52. package/dist/session/session-health.d.ts +38 -0
  53. package/dist/session/session-health.js +60 -0
  54. package/dist/session/session-keys.d.ts +51 -0
  55. package/dist/session/session-keys.js +113 -0
  56. package/dist/session/session-manager.d.ts +59 -0
  57. package/dist/session/session-manager.js +94 -0
  58. package/dist/session/session-metrics.d.ts +33 -0
  59. package/dist/session/session-metrics.js +112 -0
  60. package/dist/session/session-repository.d.ts +161 -0
  61. package/dist/session/session-repository.js +683 -0
  62. package/dist/session/session-scripts.d.ts +36 -0
  63. package/dist/session/session-scripts.js +130 -0
  64. package/dist/session/session-serializer.d.ts +42 -0
  65. package/dist/session/session-serializer.js +248 -0
  66. package/dist/session/session-service.d.ts +104 -0
  67. package/dist/session/session-service.js +611 -0
  68. package/dist/session/session-token.d.ts +38 -0
  69. package/dist/session/session-token.js +86 -0
  70. package/dist/session/session-types.d.ts +253 -0
  71. package/dist/session/session-types.js +16 -0
  72. package/dist/types.d.ts +782 -0
  73. package/dist/types.js +140 -0
  74. package/package.json +97 -0
@@ -0,0 +1,4 @@
1
+ /** Extracts the Redis Cluster hash tag from a key. */
2
+ export declare function hashTag(key: string): string;
3
+ /** Returns the Redis Cluster hash slot for a key (0..16383). */
4
+ export declare function calculateRedisClusterSlot(key: string): number;
@@ -0,0 +1,31 @@
1
+ /** Redis Cluster uses CRC16-CCITT/XMODEM over the hash-tagged key bytes. */
2
+ const CRC16_TABLE = (() => {
3
+ const table = new Uint16Array(256);
4
+ for (let i = 0; i < 256; i++) {
5
+ let crc = i << 8;
6
+ for (let bit = 0; bit < 8; bit++) {
7
+ crc = (crc & 0x8000) !== 0
8
+ ? ((crc << 1) ^ 0x1021) & 0xffff
9
+ : (crc << 1) & 0xffff;
10
+ }
11
+ table[i] = crc;
12
+ }
13
+ return table;
14
+ })();
15
+ /** Extracts the Redis Cluster hash tag from a key. */
16
+ export function hashTag(key) {
17
+ const start = key.indexOf("{");
18
+ if (start < 0)
19
+ return key;
20
+ const end = key.indexOf("}", start + 1);
21
+ return end > start + 1 ? key.slice(start + 1, end) : key;
22
+ }
23
+ /** Returns the Redis Cluster hash slot for a key (0..16383). */
24
+ export function calculateRedisClusterSlot(key) {
25
+ const bytes = Buffer.from(hashTag(key), "utf8");
26
+ let crc = 0;
27
+ for (const byte of bytes) {
28
+ crc = ((crc << 8) ^ CRC16_TABLE[((crc >>> 8) ^ byte) & 0xff]) & 0xffff;
29
+ }
30
+ return crc % 16384;
31
+ }
@@ -0,0 +1,79 @@
1
+ import type { RedisClientWrapper } from './client.js';
2
+ /** A single queued pipeline command. */
3
+ export interface PipelineCommand {
4
+ /** ioredis command name, e.g. `'get'`, `'del'`. */
5
+ command: string;
6
+ /** Arguments for the command (key first for routed commands). */
7
+ args: unknown[];
8
+ /** Slot for the key this command targets (computed by the caller). */
9
+ slot: number;
10
+ }
11
+ /** Result of one pipelined command: `[error, value]` like ioredis. */
12
+ export type PipelineCommandResult = [Error | null, unknown];
13
+ /** Options for {@link executeBySlot}. */
14
+ export interface ExecuteBySlotOptions {
15
+ /**
16
+ * Maximum number of slot pipelines to run concurrently.
17
+ * Default: 8.
18
+ */
19
+ concurrency?: number;
20
+ /**
21
+ * When a whole slot pipeline fails at the network level (rejected promise,
22
+ * e.g. connection loss), how many times it may be retried before the error
23
+ * is reported per command. Command-level errors are never retried.
24
+ * Default: 1. Pass `false` to disable retries.
25
+ *
26
+ * Only safe for idempotent command batches; the caller decides.
27
+ */
28
+ retry?: number | false;
29
+ }
30
+ /**
31
+ * Executes a batch of commands grouped by Redis hash slot.
32
+ *
33
+ * For every distinct slot the commands are collected into one pipeline and
34
+ * executed on the node owning that slot. Pipelines run with bounded
35
+ * concurrency (default 8 slots at a time) so a fan-out over many slots cannot
36
+ * exhaust sockets or event-loop resources.
37
+ *
38
+ * Result ordering is preserved: the returned array mirrors the input array.
39
+ * Command-level failures do NOT reject the whole call; each entry is reported
40
+ * as `[error, null]` so callers can implement partial-failure handling.
41
+ * Network-level pipeline failures are retried once per slot pipeline before
42
+ * being reported per command.
43
+ *
44
+ * @param client - The Redis client wrapper.
45
+ * @param commands - Commands to run, each with a resolved slot.
46
+ * @param options - Concurrency and retry tuning.
47
+ * @returns One result per input command, in input order.
48
+ */
49
+ export declare function executeBySlot(client: RedisClientWrapper, commands: PipelineCommand[], options?: ExecuteBySlotOptions): Promise<PipelineCommandResult[]>;
50
+ /**
51
+ * Inspects ioredis pipeline results and throws a structured error if any
52
+ * command failed. Returns the values (without errors) on success.
53
+ *
54
+ * Pipeline `exec()` resolves with `[error, value][]` per command; a resolved
55
+ * promise does NOT mean every command succeeded. Use this helper to enforce
56
+ * command-level error handling.
57
+ *
58
+ * @param results - The `exec()` result array.
59
+ * @param describe - Optional per-index description used in the error message
60
+ * (must not contain sensitive data).
61
+ * @throws {Error} Listing the failed command indexes.
62
+ */
63
+ export declare function assertPipelineOk(results: PipelineCommandResult[] | null, describe?: (index: number) => string): unknown[];
64
+ /**
65
+ * Runs an async map over a list with bounded concurrency.
66
+ *
67
+ * Do NOT use `Promise.all(list.map(fn))` for cross-slot fan-out; use this to
68
+ * keep the number of in-flight Redis operations bounded.
69
+ *
70
+ * @param items - Input list.
71
+ * @param limit - Maximum concurrent workers.
72
+ * @param fn - Async mapper.
73
+ * @returns Results in input order.
74
+ */
75
+ export declare function mapWithConcurrency<T, R>(items: readonly T[], limit: number, fn: (item: T, index: number) => Promise<R>): Promise<R[]>;
76
+ /**
77
+ * Chunks an array into bounded batches. Yields nothing for an empty array.
78
+ */
79
+ export declare function chunk<T>(items: readonly T[], size: number): Generator<T[]>;
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Executes a batch of commands grouped by Redis hash slot.
3
+ *
4
+ * For every distinct slot the commands are collected into one pipeline and
5
+ * executed on the node owning that slot. Pipelines run with bounded
6
+ * concurrency (default 8 slots at a time) so a fan-out over many slots cannot
7
+ * exhaust sockets or event-loop resources.
8
+ *
9
+ * Result ordering is preserved: the returned array mirrors the input array.
10
+ * Command-level failures do NOT reject the whole call; each entry is reported
11
+ * as `[error, null]` so callers can implement partial-failure handling.
12
+ * Network-level pipeline failures are retried once per slot pipeline before
13
+ * being reported per command.
14
+ *
15
+ * @param client - The Redis client wrapper.
16
+ * @param commands - Commands to run, each with a resolved slot.
17
+ * @param options - Concurrency and retry tuning.
18
+ * @returns One result per input command, in input order.
19
+ */
20
+ export async function executeBySlot(client, commands, options = {}) {
21
+ if (commands.length === 0)
22
+ return [];
23
+ const concurrency = Math.max(1, options.concurrency ?? 8);
24
+ const results = new Array(commands.length);
25
+ const missing = new Array(commands.length).fill(false);
26
+ // Group by slot, remembering the original indexes so ordering is preserved.
27
+ const groups = new Map();
28
+ for (let i = 0; i < commands.length; i++) {
29
+ const command = commands[i];
30
+ const group = groups.get(command.slot);
31
+ if (group) {
32
+ group.push({ index: i, command });
33
+ }
34
+ else {
35
+ groups.set(command.slot, [{ index: i, command }]);
36
+ }
37
+ }
38
+ const entries = Array.from(groups.entries());
39
+ // Bounded concurrency: run at most `concurrency` slot pipelines at once.
40
+ let cursor = 0;
41
+ const workers = Array.from({ length: Math.min(concurrency, entries.length) }, async () => {
42
+ while (cursor < entries.length) {
43
+ const [slot, group] = entries[cursor++];
44
+ await runSlotPipeline(client, slot, group, results, missing, options);
45
+ }
46
+ });
47
+ await Promise.all(workers);
48
+ for (let i = 0; i < missing.length; i++) {
49
+ if (missing[i]) {
50
+ results[i] = [new Error('Command did not produce a pipeline result'), null];
51
+ }
52
+ }
53
+ return results;
54
+ }
55
+ async function runSlotPipeline(client, slot, group, results, missing, options) {
56
+ const retries = options.retry === false ? 0 : Math.max(0, options.retry ?? 1);
57
+ let lastError = null;
58
+ for (let attempt = 0; attempt <= retries; attempt++) {
59
+ try {
60
+ const pipeline = client.pipeline();
61
+ for (const { command } of group) {
62
+ // `args` are formatted for the ioredis pipeline method signature.
63
+ const fn = pipeline[command.command];
64
+ fn.call(pipeline, ...command.args);
65
+ }
66
+ const raw = await pipeline.exec();
67
+ const resultsArray = Array.isArray(raw) ? raw : [];
68
+ for (let i = 0; i < group.length; i++) {
69
+ const item = group[i];
70
+ const result = resultsArray[i];
71
+ if (Array.isArray(result) && result.length === 2) {
72
+ results[item.index] = result;
73
+ }
74
+ else {
75
+ missing[item.index] = true;
76
+ }
77
+ }
78
+ return;
79
+ }
80
+ catch (error) {
81
+ lastError = error instanceof Error ? error : new Error(String(error));
82
+ // Network-level failure: retry the whole slot pipeline.
83
+ }
84
+ }
85
+ // All retries exhausted: report the network error on every command.
86
+ for (const item of group) {
87
+ results[item.index] = [lastError, null];
88
+ }
89
+ }
90
+ /**
91
+ * Inspects ioredis pipeline results and throws a structured error if any
92
+ * command failed. Returns the values (without errors) on success.
93
+ *
94
+ * Pipeline `exec()` resolves with `[error, value][]` per command; a resolved
95
+ * promise does NOT mean every command succeeded. Use this helper to enforce
96
+ * command-level error handling.
97
+ *
98
+ * @param results - The `exec()` result array.
99
+ * @param describe - Optional per-index description used in the error message
100
+ * (must not contain sensitive data).
101
+ * @throws {Error} Listing the failed command indexes.
102
+ */
103
+ export function assertPipelineOk(results, describe) {
104
+ if (!results) {
105
+ throw new Error('Pipeline returned no results (connection likely lost).');
106
+ }
107
+ const failures = [];
108
+ for (let i = 0; i < results.length; i++) {
109
+ const result = results[i];
110
+ const error = Array.isArray(result) ? result[0] : undefined;
111
+ if (error) {
112
+ const label = describe ? `"${describe(i)}"` : `index ${i}`;
113
+ failures.push(`${label}: ${error.message}`);
114
+ }
115
+ }
116
+ if (failures.length > 0) {
117
+ throw new Error(`Pipeline failed for ${failures.length} command(s): ${failures.join('; ')}`);
118
+ }
119
+ return results.map((r) => (Array.isArray(r) ? r[1] : undefined));
120
+ }
121
+ /**
122
+ * Runs an async map over a list with bounded concurrency.
123
+ *
124
+ * Do NOT use `Promise.all(list.map(fn))` for cross-slot fan-out; use this to
125
+ * keep the number of in-flight Redis operations bounded.
126
+ *
127
+ * @param items - Input list.
128
+ * @param limit - Maximum concurrent workers.
129
+ * @param fn - Async mapper.
130
+ * @returns Results in input order.
131
+ */
132
+ export async function mapWithConcurrency(items, limit, fn) {
133
+ if (items.length === 0)
134
+ return [];
135
+ const concurrency = Math.max(1, limit);
136
+ const results = new Array(items.length);
137
+ let cursor = 0;
138
+ const workers = Array.from({ length: Math.min(concurrency, items.length) }, async () => {
139
+ while (cursor < items.length) {
140
+ const index = cursor++;
141
+ results[index] = await fn(items[index], index);
142
+ }
143
+ });
144
+ await Promise.all(workers);
145
+ return results;
146
+ }
147
+ /**
148
+ * Chunks an array into bounded batches. Yields nothing for an empty array.
149
+ */
150
+ export function chunk(items, size) {
151
+ return (function* () {
152
+ for (let i = 0; i < items.length; i += size) {
153
+ yield items.slice(i, i + size);
154
+ }
155
+ })();
156
+ }
@@ -0,0 +1,30 @@
1
+ export declare class RedisError extends Error {
2
+ code: string;
3
+ details?: Record<string, any>;
4
+ constructor(message: string, code?: string, details?: Record<string, any>);
5
+ }
6
+ export declare class ConnectionError extends RedisError {
7
+ constructor(message: string, details?: Record<string, any>);
8
+ }
9
+ export declare class TimeoutError extends RedisError {
10
+ constructor(message: string, details?: Record<string, any>);
11
+ }
12
+ /** Session referenced by a token no longer exists or has expired. */
13
+ export declare class SessionExpiredError extends RedisError {
14
+ constructor(message: string, details?: Record<string, any>);
15
+ }
16
+ export declare class LockError extends RedisError {
17
+ constructor(message: string, details?: Record<string, any>);
18
+ }
19
+ export declare class SerializationError extends RedisError {
20
+ constructor(message: string, details?: Record<string, any>);
21
+ }
22
+ export declare class CompressionError extends RedisError {
23
+ constructor(message: string, details?: Record<string, any>);
24
+ }
25
+ export declare class ConfigurationError extends RedisError {
26
+ constructor(message: string, details?: Record<string, any>);
27
+ }
28
+ export declare class ClusterError extends RedisError {
29
+ constructor(message: string, details?: Record<string, any>);
30
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,63 @@
1
+ export class RedisError extends Error {
2
+ code;
3
+ details;
4
+ constructor(message, code = 'UNKNOWN_ERROR', details) {
5
+ super(message);
6
+ this.name = 'RedisError';
7
+ this.code = code;
8
+ this.details = details;
9
+ // Maintains proper stack trace for where our error was thrown (only available on V8)
10
+ if (Error.captureStackTrace) {
11
+ Error.captureStackTrace(this, RedisError);
12
+ }
13
+ }
14
+ }
15
+ export class ConnectionError extends RedisError {
16
+ constructor(message, details) {
17
+ super(message, 'CONNECTION_ERROR', details);
18
+ this.name = 'ConnectionError';
19
+ }
20
+ }
21
+ export class TimeoutError extends RedisError {
22
+ constructor(message, details) {
23
+ super(message, 'TIMEOUT_ERROR', details);
24
+ this.name = 'TimeoutError';
25
+ }
26
+ }
27
+ /** Session referenced by a token no longer exists or has expired. */
28
+ export class SessionExpiredError extends RedisError {
29
+ constructor(message, details) {
30
+ super(message, 'AUTH_SESSION_EXPIRED', details);
31
+ this.name = 'SessionExpiredError';
32
+ }
33
+ }
34
+ export class LockError extends RedisError {
35
+ constructor(message, details) {
36
+ super(message, 'LOCK_ERROR', details);
37
+ this.name = 'LockError';
38
+ }
39
+ }
40
+ export class SerializationError extends RedisError {
41
+ constructor(message, details) {
42
+ super(message, 'SERIALIZATION_ERROR', details);
43
+ this.name = 'SerializationError';
44
+ }
45
+ }
46
+ export class CompressionError extends RedisError {
47
+ constructor(message, details) {
48
+ super(message, 'COMPRESSION_ERROR', details);
49
+ this.name = 'CompressionError';
50
+ }
51
+ }
52
+ export class ConfigurationError extends RedisError {
53
+ constructor(message, details) {
54
+ super(message, 'CONFIGURATION_ERROR', details);
55
+ this.name = 'ConfigurationError';
56
+ }
57
+ }
58
+ export class ClusterError extends RedisError {
59
+ constructor(message, details) {
60
+ super(message, 'CLUSTER_ERROR', details);
61
+ this.name = 'ClusterError';
62
+ }
63
+ }
@@ -0,0 +1,39 @@
1
+ import { RedisClientWrapper } from './client.js';
2
+ import { LoggerLike } from './logger.js';
3
+ export interface HealthStatus {
4
+ healthy: boolean;
5
+ status: 'healthy' | 'degraded' | 'unhealthy';
6
+ latency: number;
7
+ timestamp: Date;
8
+ details: {
9
+ ping: boolean;
10
+ connections?: number;
11
+ memory?: string;
12
+ };
13
+ }
14
+ export declare class HealthChecker {
15
+ private client;
16
+ private logger;
17
+ private timer;
18
+ private callbacks;
19
+ private lastStatus;
20
+ constructor(client: RedisClientWrapper, logger?: LoggerLike);
21
+ start(interval?: number): void;
22
+ stop(): void;
23
+ check(): Promise<HealthStatus>;
24
+ /**
25
+ * Returns the most recent health check result.
26
+ *
27
+ * @returns The last {@link HealthStatus}, or `null` before the first check.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * const status = health.getStatus();
32
+ * console.log(status?.healthy, status?.latency);
33
+ * ```
34
+ */
35
+ getStatus(): HealthStatus | null;
36
+ onChange(callback: (status: HealthStatus) => void): void;
37
+ private notifyCallbacks;
38
+ waitForHealthy(timeout?: number): Promise<boolean>;
39
+ }
package/dist/health.js ADDED
@@ -0,0 +1,106 @@
1
+ import { defaultLogger } from './logger.js';
2
+ export class HealthChecker {
3
+ client;
4
+ logger;
5
+ timer = null;
6
+ callbacks = [];
7
+ lastStatus = null;
8
+ constructor(client, logger = defaultLogger) {
9
+ this.client = client;
10
+ this.logger = logger.child({ component: 'HealthChecker' });
11
+ }
12
+ start(interval = 10000) {
13
+ if (this.timer) {
14
+ clearInterval(this.timer);
15
+ }
16
+ this.timer = setInterval(() => {
17
+ this.check().catch((error) => {
18
+ this.logger.error('Health check failed:', error);
19
+ });
20
+ }, interval);
21
+ this.logger.info(`Health checker started (interval: ${interval}ms)`);
22
+ }
23
+ stop() {
24
+ if (this.timer) {
25
+ clearInterval(this.timer);
26
+ this.timer = null;
27
+ this.logger.info('Health checker stopped');
28
+ }
29
+ }
30
+ async check() {
31
+ const start = Date.now();
32
+ const details = {
33
+ ping: false,
34
+ };
35
+ try {
36
+ const ping = await this.client.ping();
37
+ details.ping = ping;
38
+ // Try to get some info
39
+ try {
40
+ const info = await this.client.raw.info();
41
+ const connections = info.match(/connected_clients:(\d+)/)?.[1];
42
+ const memory = info.match(/used_memory_human:([^\n]+)/)?.[1];
43
+ if (connections)
44
+ details.connections = parseInt(connections, 10);
45
+ if (memory)
46
+ details.memory = memory.trim();
47
+ }
48
+ catch {
49
+ // Info not available in cluster mode
50
+ }
51
+ }
52
+ catch (error) {
53
+ this.logger.error('Health check error:', error);
54
+ details.ping = false;
55
+ }
56
+ const latency = Date.now() - start;
57
+ const healthy = details.ping;
58
+ const status = {
59
+ healthy,
60
+ status: healthy ? 'healthy' : 'unhealthy',
61
+ latency,
62
+ timestamp: new Date(),
63
+ details,
64
+ };
65
+ this.lastStatus = status;
66
+ this.notifyCallbacks(status);
67
+ return status;
68
+ }
69
+ /**
70
+ * Returns the most recent health check result.
71
+ *
72
+ * @returns The last {@link HealthStatus}, or `null` before the first check.
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * const status = health.getStatus();
77
+ * console.log(status?.healthy, status?.latency);
78
+ * ```
79
+ */
80
+ getStatus() {
81
+ return this.lastStatus;
82
+ }
83
+ onChange(callback) {
84
+ this.callbacks.push(callback);
85
+ }
86
+ notifyCallbacks(status) {
87
+ for (const callback of this.callbacks) {
88
+ try {
89
+ callback(status);
90
+ }
91
+ catch (error) {
92
+ this.logger.error('Callback error:', error);
93
+ }
94
+ }
95
+ }
96
+ async waitForHealthy(timeout = 30000) {
97
+ const start = Date.now();
98
+ while (Date.now() - start < timeout) {
99
+ const status = await this.check();
100
+ if (status.healthy)
101
+ return true;
102
+ await new Promise(resolve => setTimeout(resolve, 1000));
103
+ }
104
+ return false;
105
+ }
106
+ }
@@ -0,0 +1,51 @@
1
+ export { RedisClientWrapper as RedisClient, createRedisClient } from './client.js';
2
+ export type { RedisClientForMode, ClusterCapabilities } from './client.js';
3
+ export { Cache } from './cache.js';
4
+ export { PubSub } from './pubsub.js';
5
+ export { DistributedLock } from './lock.js';
6
+ export { HealthChecker } from './health.js';
7
+ export { RateLimiter } from './ratelimiter.js';
8
+ export type { RateLimitAlgorithm, RateLimitOptions, RateLimitResult } from './ratelimiter.js';
9
+ export { createSessionManager } from './session/session-manager.js';
10
+ export { SessionManager } from './session/session-manager.js';
11
+ export type { SessionManagerOptions } from './session/session-manager.js';
12
+ export { SessionService } from './session/session-service.js';
13
+ export type { SessionServiceDeps } from './session/session-service.js';
14
+ export { SessionRepository } from './session/session-repository.js';
15
+ export { SessionKeyStrategy, encodeUserId } from './session/session-keys.js';
16
+ export { SessionTokenManager } from './session/session-token.js';
17
+ export { SessionMetrics } from './session/session-metrics.js';
18
+ export type { SessionMetricsAdapter } from './session/session-metrics.js';
19
+ export { SessionCircuitBreaker } from './session/session-circuit-breaker.js';
20
+ export type { CircuitBreakerState } from './session/session-circuit-breaker.js';
21
+ export { SessionHealthChecker } from './session/session-health.js';
22
+ export type { SessionHealthStatus } from './session/session-health.js';
23
+ export { SessionCookieManager, type SerializeCookieOptions, type SerializedCookie, type SerializedCookieAttributes, } from './session/session-cookie.js';
24
+ export { parseSessionConfig, redactSessionConfig, TTL, IDLE_TIMEOUT, TOUCH_INTERVAL, } from './session/session-config.js';
25
+ export type { SessionConfig, SessionConfigInput, PartialSessionConfig, } from './session/session-config.js';
26
+ export { SessionError, SessionNotFoundError, SessionExpiredError, SessionRevokedError, SessionInvalidError, SessionRotationError, SessionReplayError, SessionStorageError, SessionSerializationError, SessionConfigurationError, SessionConcurrencyError, RevocationError, RevocationBatchError, CircuitBreakerOpenError, redactIdentifier, } from './session/session-errors.js';
27
+ export { serializeSession, serializeEncryptedSession, deserializeSession, validateSessionRecord, envelopeKind, encryptedHeaderOf, assertHeaderMatches, } from './session/session-serializer.js';
28
+ export { StaticSessionKeyProvider, createRandomSessionKeyProvider, toKeyBuffer, } from './session/session-encryption.js';
29
+ export type { SessionKeyProvider } from './session/session-encryption.js';
30
+ export type { SessionRecord, SessionCreateInput, SessionUpdatePatch, CreatedSession, RotatedSession, SessionValidationResult, SessionInvalidReason, TouchOutcome, SessionEnvelope, EncryptedSessionEnvelope, PlainSessionEnvelope, ListOptions, RotateOptions, TouchOptions, UpdateOptions, ValidateOptions, BindingMismatch, } from './session/session-types.js';
31
+ export { RedisError } from './errors.js';
32
+ export type { RedisConfig, RedisConfigInput, RedisCommonConfigInput, RedisMode, RedisNode, StandaloneRedisConfig, SentinelRedisConfig, ClusterRedisConfig, RedisConfigForMode, CacheOptions, LockOptions, LockInfo, DistributedLockOptions, HealthStatus, PubSubStats, PubSubMessage, ClusterInfo, ClusterSlotRange, ConnectionStatus, Redis } from './types.js';
33
+ export { RedisConfigSchema } from './types.js';
34
+ export { calculateRedisClusterSlot, hashTag } from './cluster-slot.js';
35
+ export type { RedisConfig as RedisConfiguration } from './types.js';
36
+ import { RedisClientWrapper as RedisClient, createRedisClient } from './client.js';
37
+ import { Cache } from './cache.js';
38
+ import { PubSub } from './pubsub.js';
39
+ import { DistributedLock } from './lock.js';
40
+ import { HealthChecker } from './health.js';
41
+ import { RateLimiter } from './ratelimiter.js';
42
+ declare const _default: {
43
+ RedisClient: typeof RedisClient;
44
+ createRedisClient: typeof createRedisClient;
45
+ Cache: typeof Cache;
46
+ PubSub: typeof PubSub;
47
+ DistributedLock: typeof DistributedLock;
48
+ HealthChecker: typeof HealthChecker;
49
+ RateLimiter: typeof RateLimiter;
50
+ };
51
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,44 @@
1
+ // Core exports
2
+ export { RedisClientWrapper as RedisClient, createRedisClient } from './client.js';
3
+ export { Cache } from './cache.js';
4
+ export { PubSub } from './pubsub.js';
5
+ export { DistributedLock } from './lock.js';
6
+ export { HealthChecker } from './health.js';
7
+ export { RateLimiter } from './ratelimiter.js';
8
+ // Session subsystem (new API; the legacy stores remain exported via ./session)
9
+ export { createSessionManager } from './session/session-manager.js';
10
+ export { SessionManager } from './session/session-manager.js';
11
+ export { SessionService } from './session/session-service.js';
12
+ export { SessionRepository } from './session/session-repository.js';
13
+ export { SessionKeyStrategy, encodeUserId } from './session/session-keys.js';
14
+ export { SessionTokenManager } from './session/session-token.js';
15
+ export { SessionMetrics } from './session/session-metrics.js';
16
+ export { SessionCircuitBreaker } from './session/session-circuit-breaker.js';
17
+ export { SessionHealthChecker } from './session/session-health.js';
18
+ export { SessionCookieManager, } from './session/session-cookie.js';
19
+ export { parseSessionConfig, redactSessionConfig, TTL, IDLE_TIMEOUT, TOUCH_INTERVAL, } from './session/session-config.js';
20
+ export { SessionError, SessionNotFoundError, SessionExpiredError, SessionRevokedError, SessionInvalidError, SessionRotationError, SessionReplayError, SessionStorageError, SessionSerializationError, SessionConfigurationError, SessionConcurrencyError, RevocationError, RevocationBatchError, CircuitBreakerOpenError, redactIdentifier, } from './session/session-errors.js';
21
+ export { serializeSession, serializeEncryptedSession, deserializeSession, validateSessionRecord, envelopeKind, encryptedHeaderOf, assertHeaderMatches, } from './session/session-serializer.js';
22
+ export { StaticSessionKeyProvider, createRandomSessionKeyProvider, toKeyBuffer, } from './session/session-encryption.js';
23
+ // Re-export logger types for convenience
24
+ // Error exports
25
+ export { RedisError } from './errors.js';
26
+ // Zod schema
27
+ export { RedisConfigSchema } from './types.js';
28
+ export { calculateRedisClusterSlot, hashTag } from './cluster-slot.js';
29
+ // Default export
30
+ import { RedisClientWrapper as RedisClient, createRedisClient } from './client.js';
31
+ import { Cache } from './cache.js';
32
+ import { PubSub } from './pubsub.js';
33
+ import { DistributedLock } from './lock.js';
34
+ import { HealthChecker } from './health.js';
35
+ import { RateLimiter } from './ratelimiter.js';
36
+ export default {
37
+ RedisClient,
38
+ createRedisClient,
39
+ Cache,
40
+ PubSub,
41
+ DistributedLock,
42
+ HealthChecker,
43
+ RateLimiter,
44
+ };