@mrxsys/mrx-core 2.6.0 → 2.8.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.
Files changed (104) hide show
  1. package/CHANGELOG.md +84 -19
  2. package/dist/chunk-4mt568fz.js +26 -0
  3. package/dist/chunk-7g8k2epn.js +104 -0
  4. package/dist/chunk-kv9hms2z.js +28 -0
  5. package/dist/{chunk-7m70tmz2.js → chunk-m18th1g5.js} +1 -1
  6. package/dist/chunk-ncc0m208.js +8 -0
  7. package/dist/chunk-r1kcf1q6.js +62 -0
  8. package/dist/chunk-sepwfqdh.js +6 -0
  9. package/dist/chunk-snqdnkk7.js +10 -0
  10. package/dist/{chunk-9wk2pajt.js → chunk-syhskygx.js} +9 -8
  11. package/dist/{chunk-64d6w5kt.js → chunk-y78xrx17.js} +2 -2
  12. package/dist/chunk-yd82hdxv.js +6 -0
  13. package/dist/chunk-z1skzn1j.js +8 -0
  14. package/dist/modules/data/data.d.ts +1 -1
  15. package/dist/modules/database/index.js +2 -2
  16. package/dist/modules/elysia/cache/cache.d.ts +306 -0
  17. package/dist/modules/elysia/cache/index.d.ts +1 -0
  18. package/dist/modules/elysia/cache/index.js +68 -0
  19. package/dist/modules/elysia/cache/types/cacheItem.d.ts +7 -0
  20. package/dist/modules/elysia/cache/types/cacheOptions.d.ts +21 -0
  21. package/dist/modules/elysia/cache/types/index.d.ts +1 -0
  22. package/dist/modules/elysia/cache/utils/generateCacheKey.d.ts +5 -0
  23. package/dist/modules/elysia/cache/utils/index.d.ts +1 -0
  24. package/dist/modules/elysia/cache/utils/index.js +7 -0
  25. package/dist/modules/elysia/crud/crud.d.ts +1 -1
  26. package/dist/modules/elysia/crud/index.js +13 -10
  27. package/dist/modules/elysia/crud/types/crudOptions.d.ts +2 -0
  28. package/dist/modules/elysia/dbResolver/dbResolver.d.ts +1 -1
  29. package/dist/modules/elysia/dbResolver/index.js +3 -3
  30. package/dist/modules/elysia/error/index.js +11 -2
  31. package/dist/modules/elysia/rateLimit/enums/index.d.ts +1 -0
  32. package/dist/modules/elysia/rateLimit/enums/index.js +7 -0
  33. package/dist/modules/elysia/rateLimit/enums/rateLimitErrorKeys.d.ts +3 -0
  34. package/dist/modules/elysia/rateLimit/index.d.ts +1 -0
  35. package/dist/modules/elysia/rateLimit/index.js +59 -0
  36. package/dist/modules/elysia/{ratelimit/ratelimit.d.ts → rateLimit/rateLimit.d.ts} +32 -15
  37. package/dist/modules/elysia/{ratelimit → rateLimit}/types/rateLimitOptions.d.ts +7 -16
  38. package/dist/modules/jwt/enums/index.d.ts +2 -0
  39. package/dist/modules/jwt/enums/index.js +11 -0
  40. package/dist/modules/jwt/enums/jwtErrorKeys.d.ts +5 -0
  41. package/dist/modules/jwt/enums/parseHumanTimeToSecondsErrorKeys.d.ts +3 -0
  42. package/dist/modules/jwt/index.d.ts +1 -0
  43. package/dist/modules/jwt/index.js +58 -0
  44. package/dist/modules/jwt/jwt.d.ts +3 -0
  45. package/dist/modules/jwt/utils/index.d.ts +1 -0
  46. package/dist/modules/jwt/utils/index.js +9 -0
  47. package/dist/modules/jwt/utils/parseHumanTimeToSeconds.d.ts +17 -0
  48. package/dist/modules/kvStore/enums/index.d.ts +1 -0
  49. package/dist/modules/kvStore/enums/index.js +7 -0
  50. package/dist/modules/kvStore/enums/kvStoreErrorKeys.d.ts +5 -0
  51. package/dist/modules/kvStore/ioredis/index.d.ts +1 -0
  52. package/dist/modules/kvStore/ioredis/index.js +102 -0
  53. package/dist/modules/kvStore/ioredis/ioredisStore.d.ts +107 -0
  54. package/dist/modules/kvStore/memory/index.d.ts +1 -0
  55. package/dist/modules/kvStore/memory/index.js +9 -0
  56. package/dist/modules/kvStore/memory/memoryStore.d.ts +119 -0
  57. package/dist/modules/kvStore/memory/types/memoryStoreEntry.d.ts +11 -0
  58. package/dist/modules/kvStore/types/index.d.ts +1 -0
  59. package/dist/modules/kvStore/types/index.js +1 -0
  60. package/dist/modules/kvStore/types/kvStore.d.ts +81 -0
  61. package/dist/modules/repository/index.js +1 -1
  62. package/dist/modules/repository/types/queryOptions.d.ts +5 -1
  63. package/dist/modules/totp/enums/index.d.ts +1 -0
  64. package/dist/modules/totp/enums/index.js +7 -0
  65. package/dist/modules/totp/enums/totpErrorKeys.d.ts +7 -0
  66. package/dist/modules/totp/hotp.d.ts +11 -0
  67. package/dist/modules/totp/index.d.ts +3 -0
  68. package/dist/modules/totp/index.js +110 -0
  69. package/dist/modules/totp/otpAuthUri.d.ts +21 -0
  70. package/dist/modules/totp/totp.d.ts +23 -0
  71. package/dist/modules/totp/types/index.d.ts +3 -0
  72. package/dist/modules/totp/types/index.js +1 -0
  73. package/dist/modules/totp/types/otpAuthUri.d.ts +35 -0
  74. package/dist/modules/totp/types/totpOptions.d.ts +23 -0
  75. package/dist/modules/totp/types/verifyOptions.d.ts +18 -0
  76. package/dist/modules/totp/utils/base32.d.ts +19 -0
  77. package/dist/modules/totp/utils/createCounterBuffer.d.ts +8 -0
  78. package/dist/modules/totp/utils/dynamicTruncation.d.ts +9 -0
  79. package/dist/modules/totp/utils/generateHmac.d.ts +9 -0
  80. package/dist/modules/totp/utils/generateSecretBytes.d.ts +10 -0
  81. package/dist/modules/totp/utils/index.d.ts +6 -0
  82. package/dist/modules/totp/utils/index.js +81 -0
  83. package/dist/modules/totp/utils/timeRemaining.d.ts +9 -0
  84. package/dist/utils/types/index.d.ts +1 -0
  85. package/dist/utils/types/renameKey.d.ts +10 -0
  86. package/package.json +86 -75
  87. package/dist/chunk-cqw9xq4y.js +0 -7
  88. package/dist/chunk-twaga0fp.js +0 -6
  89. package/dist/modules/elysia/jwt/enums/index.d.ts +0 -1
  90. package/dist/modules/elysia/jwt/enums/index.js +0 -7
  91. package/dist/modules/elysia/jwt/enums/jwtErrorKeys.d.ts +0 -4
  92. package/dist/modules/elysia/jwt/index.d.ts +0 -1
  93. package/dist/modules/elysia/jwt/index.js +0 -77
  94. package/dist/modules/elysia/jwt/jwt.d.ts +0 -119
  95. package/dist/modules/elysia/jwt/types/index.d.ts +0 -1
  96. package/dist/modules/elysia/jwt/types/jwtOptions.d.ts +0 -98
  97. package/dist/modules/elysia/ratelimit/enums/index.d.ts +0 -1
  98. package/dist/modules/elysia/ratelimit/enums/index.js +0 -7
  99. package/dist/modules/elysia/ratelimit/enums/ratelimitErrorKeys.d.ts +0 -3
  100. package/dist/modules/elysia/ratelimit/index.d.ts +0 -1
  101. package/dist/modules/elysia/ratelimit/index.js +0 -52
  102. /package/dist/modules/elysia/{jwt → cache}/types/index.js +0 -0
  103. /package/dist/modules/elysia/{ratelimit → rateLimit}/types/index.d.ts +0 -0
  104. /package/dist/modules/elysia/{ratelimit → rateLimit}/types/index.js +0 -0
@@ -16,30 +16,47 @@ import type { RateLimitOptions } from './types/rateLimitOptions';
16
16
  * @returns An {@link Elysia} plugin that adds rate limiting functionality
17
17
  *
18
18
  * @example
19
+ * Basic usage with default in-memory store
19
20
  * ```ts
20
- * // Create Redis instance
21
- * const redis = new Redis({
21
+ * import { rateLimit } from '@nowarajs/elysia-ratelimit';
22
+ * import { Elysia } from 'elysia';
23
+ *
24
+ * const app = new Elysia()
25
+ * .use(rateLimit({
26
+ * store: ':memory:', // Use in-memory store
27
+ * limit: 100, // 100 requests
28
+ * window: 60, // per minute
29
+ * }))
30
+ * .get('/api/endpoint', () => ({ message: 'Hello World' }));
31
+ *
32
+ * app.listen(3000);
33
+ * ```
34
+ *
35
+ * @example
36
+ * Using Redis store for distributed rate limiting
37
+ * ```ts
38
+ * import { IoRedisStore } from '@nowarajs/kv-store';
39
+ * import { rateLimit } from '@nowarajs/elysia-ratelimit';
40
+ * import { Elysia } from 'elysia';
41
+ *
42
+ * const redisStore = new IoRedisStore({
22
43
  * host: 'localhost',
23
44
  * port: 6379
24
45
  * });
25
- * await redis.connect();
46
+ * await redisStore.connect();
26
47
  *
27
- * // Create and configure the application with rate limiting
28
48
  * const app = new Elysia()
29
49
  * .use(rateLimit({
30
- * redis,
31
- * limit: 100, // 100 requests
32
- * window: 60, // per minute
50
+ * store: redisStore,
51
+ * limit: 1000, // 1000 requests
52
+ * window: 3600, // per hour
33
53
  * }))
34
- * .get('/public-api', () => {
35
- * return { success: true, message: 'This endpoint is rate limited' };
36
- * });
54
+ * .get('/api/endpoint', () => ({ message: 'Hello World' }));
37
55
  *
38
- * // Start the server
39
56
  * app.listen(3000);
40
57
  * ```
41
58
  */
42
- export declare const rateLimit: ({ redis, limit, window }: RateLimitOptions) => Elysia<"", {
59
+ export declare const rateLimit: ({ store, limit, window }: RateLimitOptions) => Elysia<"", {
43
60
  decorator: {};
44
61
  store: {};
45
62
  derive: {};
@@ -48,7 +65,7 @@ export declare const rateLimit: ({ redis, limit, window }: RateLimitOptions) =>
48
65
  typebox: {};
49
66
  error: {};
50
67
  }, {
51
- schema: {};
68
+ schema: import("elysia").MergeSchema<import("elysia").MergeSchema<{}, {}, "">, {}, "">;
52
69
  standaloneSchema: {};
53
70
  macro: {};
54
71
  macroFn: {};
@@ -56,8 +73,8 @@ export declare const rateLimit: ({ redis, limit, window }: RateLimitOptions) =>
56
73
  }, {}, {
57
74
  derive: {};
58
75
  resolve: {};
59
- schema: import("elysia").MergeSchema<{}, {}, "">;
60
- standaloneSchema: import("elysia/types").PrettifySchema<{}>;
76
+ schema: {};
77
+ standaloneSchema: {};
61
78
  }, {
62
79
  derive: {};
63
80
  resolve: {};
@@ -1,22 +1,13 @@
1
- import type { Redis } from 'ioredis';
2
- /**
3
- * Options to configure the rate limit plugin.
4
- *
5
- * @example
6
- * ```ts
7
- * const options: RateLimitOptions = {
8
- * redis: redisInstance, // Your Redis instance
9
- * limit: 100, // Allow 100 requests
10
- * window: 60, // Per 60 seconds
11
- * message: 'You have exceeded the rate limit. Please try again later.'
12
- * };
13
- * ```
14
- */
1
+ import type { KvStore } from '../../../../modules/kvStore/types/kvStore';
15
2
  export interface RateLimitOptions {
16
3
  /**
17
- * Redis instance used for storing rate limit data.
4
+ * Storage backend for rate limit data.
5
+ *
6
+ * - If not specified, defaults to in-memory storage
7
+ * - Use ':memory:' to explicitly specify in-memory storage
8
+ * - Provide a KvStore instance for persistent distributed storage
18
9
  */
19
- readonly redis: Redis;
10
+ readonly store?: ':memory:' | KvStore;
20
11
  /**
21
12
  * Maximum number of requests allowed in the time window.
22
13
  *
@@ -0,0 +1,2 @@
1
+ export { JWT_ERROR_KEYS } from './jwtErrorKeys';
2
+ export { PARSE_HUMAN_TIME_TO_SECONDS_ERROR_KEYS } from './parseHumanTimeToSecondsErrorKeys';
@@ -0,0 +1,11 @@
1
+ // @bun
2
+ import {
3
+ JWT_ERROR_KEYS
4
+ } from "../../../chunk-ncc0m208.js";
5
+ import {
6
+ PARSE_HUMAN_TIME_TO_SECONDS_ERROR_KEYS
7
+ } from "../../../chunk-sepwfqdh.js";
8
+ export {
9
+ PARSE_HUMAN_TIME_TO_SECONDS_ERROR_KEYS,
10
+ JWT_ERROR_KEYS
11
+ };
@@ -0,0 +1,5 @@
1
+ export declare const JWT_ERROR_KEYS: {
2
+ readonly JWT_SIGN_ERROR: "jwt.error.sign_error";
3
+ readonly JWT_SECRET_NOT_FOUND: "jwt.error.secret_not_found";
4
+ readonly JWT_EXPIRATION_PASSED: "jwt.error.expiration_passed";
5
+ };
@@ -0,0 +1,3 @@
1
+ export declare const PARSE_HUMAN_TIME_TO_SECONDS_ERROR_KEYS: {
2
+ readonly INVALID_TIME_EXPRESSION: "parse_human_time_to_seconds.error.invalid_time_expression";
3
+ };
@@ -0,0 +1 @@
1
+ export { signJWT, verifyJWT } from './jwt';
@@ -0,0 +1,58 @@
1
+ // @bun
2
+ import {
3
+ JWT_ERROR_KEYS
4
+ } from "../../chunk-ncc0m208.js";
5
+ import {
6
+ parseHumanTimeToSeconds
7
+ } from "../../chunk-r1kcf1q6.js";
8
+ import"../../chunk-sepwfqdh.js";
9
+ import {
10
+ HttpError
11
+ } from "../../chunk-683sda6e.js";
12
+ import"../../chunk-9nw6qekv.js";
13
+ import"../../chunk-vknq69e0.js";
14
+
15
+ // source/modules/jwt/jwt.ts
16
+ import {
17
+ SignJWT,
18
+ jwtVerify
19
+ } from "jose";
20
+ var signJWT = (secret, payload, expiration = Math.floor(Date.now() / 1000) + 60 * 15) => {
21
+ const exp = expiration instanceof Date ? Math.floor(expiration.getTime() / 1000) : typeof expiration === "number" ? expiration : parseHumanTimeToSeconds(expiration);
22
+ if (exp <= Math.floor(Date.now() / 1000))
23
+ throw new HttpError({
24
+ message: JWT_ERROR_KEYS.JWT_EXPIRATION_PASSED,
25
+ httpStatusCode: "BAD_REQUEST"
26
+ });
27
+ const finalPayload = {
28
+ iss: "Core-Issuer",
29
+ sub: "",
30
+ aud: ["Core-Audience"],
31
+ jti: Bun.randomUUIDv7(),
32
+ nbf: Math.floor(Date.now() / 1000),
33
+ iat: Math.floor(Date.now() / 1000),
34
+ exp,
35
+ ...payload
36
+ };
37
+ try {
38
+ const jwt = new SignJWT(finalPayload).setProtectedHeader({ alg: "HS256", typ: "JWT" }).setIssuer(finalPayload.iss).setSubject(finalPayload.sub).setAudience(finalPayload.aud).setJti(finalPayload.jti).setNotBefore(finalPayload.nbf).setIssuedAt(finalPayload.iat).setExpirationTime(expiration).sign(new TextEncoder().encode(secret));
39
+ return jwt;
40
+ } catch (error) {
41
+ throw new HttpError({
42
+ message: JWT_ERROR_KEYS.JWT_SIGN_ERROR,
43
+ httpStatusCode: "INTERNAL_SERVER_ERROR",
44
+ cause: error
45
+ });
46
+ }
47
+ };
48
+ var verifyJWT = async (token, secret) => {
49
+ try {
50
+ return await jwtVerify(token, new TextEncoder().encode(secret));
51
+ } catch {
52
+ return false;
53
+ }
54
+ };
55
+ export {
56
+ verifyJWT,
57
+ signJWT
58
+ };
@@ -0,0 +1,3 @@
1
+ import { type JWTPayload, type JWTVerifyResult } from 'jose';
2
+ export declare const signJWT: (secret: string, payload: JWTPayload, expiration?: number | string | Date) => Promise<string>;
3
+ export declare const verifyJWT: (token: string, secret: string) => Promise<JWTVerifyResult | false>;
@@ -0,0 +1 @@
1
+ export { parseHumanTimeToSeconds } from './parseHumanTimeToSeconds';
@@ -0,0 +1,9 @@
1
+ // @bun
2
+ import {
3
+ parseHumanTimeToSeconds
4
+ } from "../../../chunk-r1kcf1q6.js";
5
+ import"../../../chunk-sepwfqdh.js";
6
+ import"../../../chunk-vknq69e0.js";
7
+ export {
8
+ parseHumanTimeToSeconds
9
+ };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Converts a human-readable time expression to seconds
3
+ *
4
+ * @param timeExpression - A string representing a time period (e.g., "2 hours", "30 minutes ago", "+1 day")
5
+ *
6
+ * @throws ({@link BaseError}) - If the time expression is invalid or contains an unknown unit
7
+ *
8
+ * @returns The time period in seconds (negative for past times)
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * parseHumanTimeToSeconds("2 hours") // Returns 7200
13
+ * parseHumanTimeToSeconds("30 mins ago") // Returns -1800
14
+ * parseHumanTimeToSeconds("+1 day") // Returns 86400
15
+ * ```
16
+ */
17
+ export declare const parseHumanTimeToSeconds: (timeExpression: string) => number;
@@ -0,0 +1 @@
1
+ export { KV_STORE_ERROR_KEYS } from './kvStoreErrorKeys';
@@ -0,0 +1,7 @@
1
+ // @bun
2
+ import {
3
+ KV_STORE_ERROR_KEYS
4
+ } from "../../../chunk-z1skzn1j.js";
5
+ export {
6
+ KV_STORE_ERROR_KEYS
7
+ };
@@ -0,0 +1,5 @@
1
+ export declare const KV_STORE_ERROR_KEYS: {
2
+ readonly NOT_INTEGER: "kv-store.error.not_integer";
3
+ readonly CONNECTION_FAILED: "kv-store.error.connection_failed";
4
+ readonly CLOSING_CONNECTION_FAILED: "kv-store.error.closing_connection_failed";
5
+ };
@@ -0,0 +1 @@
1
+ export { IoRedisStore } from './ioredisStore';
@@ -0,0 +1,102 @@
1
+ // @bun
2
+ import {
3
+ KV_STORE_ERROR_KEYS
4
+ } from "../../../chunk-z1skzn1j.js";
5
+ import {
6
+ BaseError
7
+ } from "../../../chunk-vknq69e0.js";
8
+
9
+ // source/modules/kvStore/ioredis/ioredisStore.ts
10
+ import { Redis } from "ioredis";
11
+ class IoRedisStore {
12
+ _client;
13
+ constructor(options) {
14
+ this._client = new Redis({
15
+ ...options,
16
+ lazyConnect: true
17
+ });
18
+ }
19
+ async connect() {
20
+ try {
21
+ await this._client.connect();
22
+ } catch (e) {
23
+ throw new BaseError({
24
+ message: KV_STORE_ERROR_KEYS.CONNECTION_FAILED,
25
+ cause: e
26
+ });
27
+ }
28
+ }
29
+ async close() {
30
+ try {
31
+ await this._client.quit();
32
+ } catch (e) {
33
+ throw new BaseError({
34
+ message: KV_STORE_ERROR_KEYS.CLOSING_CONNECTION_FAILED,
35
+ cause: e
36
+ });
37
+ }
38
+ }
39
+ async get(key) {
40
+ const value = await this._client.get(key);
41
+ if (value === null)
42
+ return null;
43
+ try {
44
+ return JSON.parse(value);
45
+ } catch {
46
+ return value;
47
+ }
48
+ }
49
+ async set(key, value, ttlSec) {
50
+ const serialized = typeof value === "string" ? value : JSON.stringify(value);
51
+ if (ttlSec)
52
+ await this._client.setex(key, ttlSec, serialized);
53
+ else
54
+ await this._client.set(key, serialized);
55
+ }
56
+ async increment(key, amount = 1) {
57
+ const current = await this._client.get(key);
58
+ if (current !== null) {
59
+ const parsed = Number(current);
60
+ if (Number.isNaN(parsed))
61
+ throw new BaseError({
62
+ message: KV_STORE_ERROR_KEYS.NOT_INTEGER
63
+ });
64
+ }
65
+ if (amount === 1)
66
+ return this._client.incr(key);
67
+ return this._client.incrby(key, amount);
68
+ }
69
+ async decrement(key, amount = 1) {
70
+ const current = await this._client.get(key);
71
+ if (current !== null) {
72
+ const parsed = Number(current);
73
+ if (Number.isNaN(parsed))
74
+ throw new BaseError({
75
+ message: KV_STORE_ERROR_KEYS.NOT_INTEGER
76
+ });
77
+ }
78
+ if (amount === 1)
79
+ return this._client.decr(key);
80
+ return this._client.decrby(key, amount);
81
+ }
82
+ async del(key) {
83
+ const result = await this._client.del(key);
84
+ return result === 1;
85
+ }
86
+ async expire(key, ttlSec) {
87
+ const result = await this._client.expire(key, ttlSec);
88
+ return result === 1;
89
+ }
90
+ ttl(key) {
91
+ return this._client.ttl(key);
92
+ }
93
+ async clean() {
94
+ const keys = await this._client.keys("*");
95
+ if (keys.length === 0)
96
+ return 0;
97
+ return this._client.del(...keys);
98
+ }
99
+ }
100
+ export {
101
+ IoRedisStore
102
+ };
@@ -0,0 +1,107 @@
1
+ import { type RedisOptions } from 'ioredis';
2
+ import type { KvStore } from '../../../modules/kvStore/types/kvStore';
3
+ /**
4
+ * Redis-based key-value store implementation using ioredis client.
5
+ *
6
+ * Provides a Redis-backed implementation of the KvStore interface with
7
+ * automatic JSON serialization/deserialization and proper error handling.
8
+ */
9
+ export declare class IoRedisStore implements KvStore {
10
+ /**
11
+ * Redis client instance.
12
+ */
13
+ private readonly _client;
14
+ /**
15
+ * Creates an IoRedis store instance.
16
+ *
17
+ * @param options - Redis connection options
18
+ */
19
+ constructor(options: RedisOptions);
20
+ /**
21
+ * Establishes connection to Redis server.
22
+ *
23
+ * @throws ({@link BaseError}) - When connection fails
24
+ */
25
+ connect(): Promise<void>;
26
+ /**
27
+ * Closes the Redis connection gracefully.
28
+ *
29
+ * @throws ({@link BaseError}) - When closing connection fails
30
+ */
31
+ close(): Promise<void>;
32
+ /**
33
+ * Retrieves a value from Redis by key.
34
+ *
35
+ * @template T - The expected type of the stored value
36
+ *
37
+ * @param key - The key to retrieve
38
+ *
39
+ * @returns The value associated with the key, or null if not found or expired
40
+ */
41
+ get<T = unknown>(key: string): Promise<T | null>;
42
+ /**
43
+ * Stores a value in Redis with optional TTL.
44
+ *
45
+ * @template T - The type of the value being stored
46
+ *
47
+ * @param key - The key to store the value under
48
+ * @param value - The value to store
49
+ * @param ttlSec - Time to live in seconds (optional)
50
+ */
51
+ set<T = unknown>(key: string, value: T, ttlSec?: number): Promise<void>;
52
+ /**
53
+ * Increments a numeric value stored at key by the specified amount.
54
+ * If the key does not exist, it is set to 0 before performing the operation.
55
+ *
56
+ * @param key - The key containing the numeric value
57
+ * @param amount - The amount to increment by (default: 1)
58
+ *
59
+ * @throws ({@link BaseError}) - When the value is not a valid integer
60
+ *
61
+ * @returns The value after incrementing
62
+ */
63
+ increment(key: string, amount?: number): Promise<number>;
64
+ /**
65
+ * Decrements a numeric value stored at key by the specified amount.
66
+ * If the key does not exist, it is set to 0 before performing the operation.
67
+ *
68
+ * @param key - The key containing the numeric value
69
+ * @param amount - The amount to decrement by (default: 1)
70
+ *
71
+ * @throws ({@link BaseError}) - When the value is not a valid integer
72
+ *
73
+ * @returns The value after decrementing
74
+ */
75
+ decrement(key: string, amount?: number): Promise<number>;
76
+ /**
77
+ * Deletes a key from Redis.
78
+ *
79
+ * @param key - The key to delete
80
+ *
81
+ * @returns True if the key was deleted, false if it did not exist
82
+ */
83
+ del(key: string): Promise<boolean>;
84
+ /**
85
+ * Sets an expiration time for a key.
86
+ *
87
+ * @param key - The key to set expiration for
88
+ * @param ttlSec - Time to live in seconds
89
+ *
90
+ * @returns True if the expiration was set, false if the key does not exist
91
+ */
92
+ expire(key: string, ttlSec: number): Promise<boolean>;
93
+ /**
94
+ * Gets the remaining time to live for a key.
95
+ *
96
+ * @param key - The key to check
97
+ *
98
+ * @returns Time to live in seconds, -1 if key has no expiration, -2 if key does not exist
99
+ */
100
+ ttl(key: string): Promise<number>;
101
+ /**
102
+ * Removes all keys from the Redis database.
103
+ *
104
+ * @returns The number of keys that were deleted
105
+ */
106
+ clean(): Promise<number>;
107
+ }
@@ -0,0 +1 @@
1
+ export { MemoryStore } from './memoryStore';
@@ -0,0 +1,9 @@
1
+ // @bun
2
+ import {
3
+ MemoryStore
4
+ } from "../../../chunk-7g8k2epn.js";
5
+ import"../../../chunk-z1skzn1j.js";
6
+ import"../../../chunk-vknq69e0.js";
7
+ export {
8
+ MemoryStore
9
+ };
@@ -0,0 +1,119 @@
1
+ import type { KvStore } from '../../../modules/kvStore/types/kvStore';
2
+ /**
3
+ * In-memory key-value store implementation with automatic cleanup of expired entries.
4
+ *
5
+ * Provides a memory-based implementation of the KvStore interface with TTL support
6
+ * and automatic background cleanup of expired entries.
7
+ */
8
+ export declare class MemoryStore implements KvStore {
9
+ /**
10
+ * In-memory key-value store.
11
+ */
12
+ private readonly _store;
13
+ /**
14
+ * Cleanup interval (5 minutes by default).
15
+ *
16
+ * @defaultValue 300000
17
+ */
18
+ private readonly _cleanupInterval;
19
+ /**
20
+ * Timer for cleanup operations.
21
+ */
22
+ private _cleanupTimer;
23
+ /**
24
+ * Creates instance and starts cleanup process.
25
+ *
26
+ * @param cleanupIntervalMs - Cleanup interval in milliseconds (default: 300000 ms / 5 minutes)
27
+ */
28
+ constructor(cleanupIntervalMs?: number);
29
+ /**
30
+ * Retrieves a value from the store by key.
31
+ * Automatically removes expired entries during retrieval.
32
+ *
33
+ * @template T - The expected type of the stored value
34
+ *
35
+ * @param key - The key to retrieve
36
+ *
37
+ * @returns The value associated with the key, or null if not found or expired
38
+ */
39
+ get<T = unknown>(key: string): T | null;
40
+ /**
41
+ * Stores a value in memory with optional TTL.
42
+ *
43
+ * @template T - The type of the value being stored
44
+ *
45
+ * @param key - The key to store the value under
46
+ * @param value - The value to store
47
+ * @param ttlSec - Time to live in seconds (optional)
48
+ */
49
+ set<T = unknown>(key: string, value: T, ttlSec?: number): void;
50
+ /**
51
+ * Increments a numeric value stored at key by the specified amount.
52
+ * If the key does not exist, it is set to 0 before performing the operation.
53
+ * Preserves existing TTL when incrementing.
54
+ *
55
+ * @param key - The key containing the numeric value
56
+ * @param amount - The amount to increment by (default: 1)
57
+ *
58
+ * @throws ({@link BaseError}) - When the value is not a valid integer
59
+ *
60
+ * @returns The value after incrementing
61
+ */
62
+ increment(key: string, amount?: number): number;
63
+ /**
64
+ * Decrements a numeric value stored at key by the specified amount.
65
+ * If the key does not exist, it is set to 0 before performing the operation.
66
+ * Preserves existing TTL when decrementing.
67
+ *
68
+ * @param key - The key containing the numeric value
69
+ * @param amount - The amount to decrement by (default: 1)
70
+ *
71
+ * @throws ({@link BaseError}) - When the value is not a valid integer
72
+ *
73
+ * @returns The value after decrementing
74
+ */
75
+ decrement(key: string, amount?: number): number;
76
+ /**
77
+ * Deletes a key from the store.
78
+ *
79
+ * @param key - The key to delete
80
+ *
81
+ * @returns True if the key was deleted, false if it did not exist
82
+ */
83
+ del(key: string): boolean;
84
+ /**
85
+ * Sets an expiration time for a key.
86
+ *
87
+ * @param key - The key to set expiration for
88
+ * @param ttlSec - Time to live in seconds
89
+ *
90
+ * @returns True if the expiration was set, false if the key does not exist
91
+ */
92
+ expire(key: string, ttlSec: number): boolean;
93
+ /**
94
+ * Gets the remaining time to live for a key.
95
+ *
96
+ * @param key - The key to check
97
+ *
98
+ * @returns Time to live in seconds, -1 if key has no expiration or does not exist
99
+ */
100
+ ttl(key: string): number;
101
+ /**
102
+ * Removes all keys from the store.
103
+ *
104
+ * @returns The number of keys that were deleted
105
+ */
106
+ clean(): number;
107
+ /**
108
+ * Starts the cleanup process for expired entries.
109
+ */
110
+ private _startCleanup;
111
+ /**
112
+ * Removes expired entries from the store.
113
+ */
114
+ private _removeExpiredEntries;
115
+ /**
116
+ * Stops the cleanup process and clears resources.
117
+ */
118
+ destroy(): void;
119
+ }
@@ -0,0 +1,11 @@
1
+ export interface MemoryStoreEntry {
2
+ /**
3
+ * Current count value for the key.
4
+ */
5
+ readonly value: unknown;
6
+ /**
7
+ * Timestamp when this entry expires (in milliseconds).
8
+ * -1 means no expiration (like Redis behavior).
9
+ */
10
+ expiresAt: number;
11
+ }
@@ -0,0 +1 @@
1
+ export type { KvStore } from './kvStore';
@@ -0,0 +1 @@
1
+ // @bun