express-adaptive-rate-limiter 1.0.0 → 2.0.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 (51) hide show
  1. package/README.md +250 -16
  2. package/dist/algorithms/baseAlgorithm.js +1 -1
  3. package/dist/algorithms/fixedWindow.js +1 -1
  4. package/dist/algorithms/leakyBucket.js +1 -1
  5. package/dist/algorithms/slidingWindowCounter.js +1 -1
  6. package/dist/algorithms/slidingWindowLog.js +1 -1
  7. package/dist/algorithms/tokenBucket.js +1 -1
  8. package/dist/core/blockedKeys.js +1 -0
  9. package/dist/core/coreMiddleware.js +1 -0
  10. package/dist/core/limiters/clusterLimiter.js +16 -0
  11. package/dist/core/limiters/dynamoDbLimiter.js +1 -0
  12. package/dist/core/limiters/etcdLimiter.js +1 -0
  13. package/dist/core/limiters/memcachedLimiter.js +1 -0
  14. package/dist/core/limiters/memoryLimiter.js +1 -0
  15. package/dist/core/limiters/mongoLimiter.js +1 -0
  16. package/dist/core/limiters/mongooseLimiter.js +1 -0
  17. package/dist/core/limiters/mySqlLimiter.js +12 -0
  18. package/dist/core/limiters/nodeClusterLimiter.js +1 -0
  19. package/dist/core/limiters/postgresLimiter.js +13 -0
  20. package/dist/core/limiters/prismaLimiter.js +24 -0
  21. package/dist/core/limiters/redisLimiter.js +16 -0
  22. package/dist/core/limiters/sqliteLimiter.js +13 -0
  23. package/dist/core/limiters/valkeyLimiter.js +16 -0
  24. package/dist/core/rateLimiter.js +1 -0
  25. package/dist/core/rateLimiterRes.js +1 -0
  26. package/dist/core/rateLimiterStore.js +1 -0
  27. package/dist/core/wrappers/blackAndWhiteLimiter.js +1 -0
  28. package/dist/core/wrappers/burstyRateLimiter.js +1 -0
  29. package/dist/core/wrappers/rateLimiterQueue.js +1 -0
  30. package/dist/core/wrappers/rateLimiterUnion.js +1 -0
  31. package/dist/core/wrappers/timeoutLimiter.js +1 -0
  32. package/dist/index.js +1 -1
  33. package/dist/middleware/expressMiddleware.js +1 -1
  34. package/dist/middleware/headers.js +1 -1
  35. package/dist/rateLimit.js +1 -1
  36. package/dist/rateLimitManager.js +1 -1
  37. package/dist/stores/baseStore.js +1 -1
  38. package/dist/stores/luaScripts.js +379 -1
  39. package/dist/stores/memoryStore.js +1 -1
  40. package/dist/stores/redisStore.js +1 -1
  41. package/dist/types/index.d.ts +507 -0
  42. package/dist/utils/errors.js +1 -1
  43. package/dist/utils/graphQLParser.js +1 -1
  44. package/dist/utils/ipUtils.js +1 -1
  45. package/dist/utils/keyGenerator.js +1 -1
  46. package/dist/utils/redisClient.js +1 -0
  47. package/dist/utils/retryAfter.js +1 -1
  48. package/dist/utils/skipUtils.js +1 -1
  49. package/dist/utils/time.js +1 -1
  50. package/dist/utils/validation.js +1 -1
  51. package/package.json +67 -4
@@ -1 +1,379 @@
1
- function _0x2e06(_0x48d999,_0x41ffd4){_0x48d999=_0x48d999-326;const _0x38b4d6=_0x38b4();let _0x2e0634=_0x38b4d6[_0x48d999];if(_0x2e06["QIujAb"]===undefined){var _0x116e7d=function(_0x17592f){const _0x182637="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=";let _0x57312c="",_0x1f4116="";for(let _0xea548c=0,_0x2e06ed,_0x2b9380,_0x36a26a=0;_0x2b9380=_0x17592f["charAt"](_0x36a26a++);~_0x2b9380&&(_0x2e06ed=_0xea548c%4?_0x2e06ed*64+_0x2b9380:_0x2b9380,_0xea548c++%4)?_0x57312c+=String["fromCharCode"](255&_0x2e06ed>>(-2*_0xea548c&6)):0){_0x2b9380=_0x182637["indexOf"](_0x2b9380)}for(let _0x26aee9=0,_0x1c3f96=_0x57312c["length"];_0x26aee9<_0x1c3f96;_0x26aee9++){_0x1f4116+="%"+("00"+_0x57312c["charCodeAt"](_0x26aee9)["toString"](16))["slice"](-2)}return decodeURIComponent(_0x1f4116)};_0x2e06["ZmMjrt"]=_0x116e7d,_0x2e06["RQQvlL"]={},_0x2e06["QIujAb"]=!![]}const _0x325962=_0x38b4d6[0];_0x2e06["Pvqlrw"]!==_0x325962&&(_0x2e06["RQQvlL"]={},_0x2e06["Pvqlrw"]=_0x325962);const _0x4763e4=_0x2e06["RQQvlL"][_0x48d999];return _0x4763e4===undefined?(_0x2e0634=_0x2e06["ZmMjrt"](_0x2e0634),_0x2e06["RQQvlL"][_0x48d999]=_0x2e0634):_0x2e0634=_0x4763e4,_0x2e0634}const _0x53dc29=_0x2e06;(function(_0x2bde2c,_0x32351c){const _0xb47721=_0x2e06,_0x87b691=_0x2bde2c();while(!![]){try{const _0x58c220=parseInt(_0xb47721(337))/1+-parseInt(_0xb47721(335))/2*(parseInt(_0xb47721(342))/3)+-parseInt(_0xb47721(326))/4*(parseInt(_0xb47721(333))/5)+-parseInt(_0xb47721(340))/6+-parseInt(_0xb47721(329))/7+-parseInt(_0xb47721(330))/8+parseInt(_0xb47721(338))/9*(parseInt(_0xb47721(331))/10);if(_0x58c220===_0x32351c)break;else _0x87b691["push"](_0x87b691["shift"]())}catch(_0x3eaa66){_0x87b691["push"](_0x87b691["shift"]())}}})(_0x38b4,511188);function _0x38b4(){const _0x5cbfa5=["ouXswwTtuG","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","ntC5mJqZnNLYvvLzAa","C2HHmq","ntC5mJK0sgjsBwfg","mJeXnLLVt21nqW","y3jLyxrLsgfZAa","zw50CMLLCW","nJiYnZm0shnzyw9l","nZe5mJG2nhf3BuP1za","mJKYnty3mZbLDeLuAxi","DxbKyxrL","mZK0mgXpquzbva","cMXVy2fSig5VDWPPzIbbuKDwwZrDigfUzcb0B251BwjLCIHbuKDwwZrDksbHBMqGDg9UDw1IzxiOqvjhvLS0xsKGpIaWihrOzw4kicbUB3CGpsbTyxrOlMzSB29YkhrVBNvTyMvYkefsr1zBnf0PkqPLBhnLcIaGBg9JywWGDgLTzv9YzxmGpsbYzwrPCY5JywXSkcDusu1fjYKkicbUB3CGpsbTyxrOlMzSB29YkhrVBNvTyMvYkhrPBwvFCMvZwZfDksaQideWmdaUmcaRicH0B251BwjLCIH0Aw1Lx3jLC1SYxsKGlYaXmdaWlJaPkqPLBMqkcMXVy2fSigXPBwL0id0GDg9UDw1IzxiOqvjhvLSXxsKGkIaXlJakBg9JywWGD2LUzg93txmGpsb0B251BwjLCIHbuKDwwZjDksaQideUmaPSB2nHBcbJB3n0id0GDg9UDw1IzxiOqvjhvLSZxsKGkIaXlJakcMXVy2fSihDPBMrVD1n0yxj0id0GBwf0Ac5MBg9VCIHUB3CGlYb3Aw5KB3DnCYKGkIb3Aw5KB3DnCWPSB2nHBcbYzxnLDfrPBwuGpsb3Aw5KB3DtDgfYDcaRihDPBMrVD01ZcMXVy2fSihb0DgWGpsbTyxrOlMzSB29YkhjLC2v0vgLTzsaTig5VDYKkAwyGChr0Bca8psaWihrOzw4kicbWDhrSid0GmqPLBMqkcMXVy2fSigrHDgeGpsbYzwrPCY5JywXSkcDituDfvcCSieTfwvnBmv0SicDJB3vUDcCSicD3Aw5KB3DtDgfYDcCPcMXVy2fSihn0B3jLzenVDw50id0GDg9UDw1IzxiOzgf0yvSXxsKGB3iGmaPSB2nHBcbZDg9YzwrxAw5KB3CGpsb0B251BwjLCIHKyxrHwZjDksbVCIaWcGPSB2nHBcbJDxjYzw50cMLMihn0B3jLzfDPBMrVDYb+psb3Aw5KB3DtDgfYDcb0AgvUcIaGy3vYCMvUDca9ignVC3qkzwXZzqOGign1CNjLBNqGpsbZDg9YzwrdB3vUDcaRignVC3qkzw5KcGPPzIbJB3n0id09idaGDgHLBGOGigXVy2fSigfJDhvHBen1CNjLBNqGpsaWcIaGAwyGC3rVCMvKv2LUzg93id09ihDPBMrVD1n0yxj0ihrOzw4kicaGigfJDhvHBen1CNjLBNqGpsbZDg9YzwrdB3vUDaOGigvUzaOGigXVy2fSihjLBwfPBMLUzYa9ig1HDgGUBwf4kdaSigXPBwL0ic0Gywn0DwfSq3vYCMvUDcKkicbSB2nHBcbPC0fSBg93zwqGpsaXcIaGBg9JywWGCMv0CNLbzNrLCIa9idakicbPzIbHy3r1ywXdDxjYzw50id49igXPBwL0ihrOzw4kicaGigLZqwXSB3DLzca9idakicaGihjLDhj5qwz0zxiGpsbTyxrOlMnLAwWOChr0BcaVideWmdaUmcKkicaGigLMihjLDhj5qwz0zxiGpcaXihrOzw4GCMv0CNLbzNrLCIa9ideGzw5KcIaGzw5KcIaGCMv0DxjUihSGAxnbBgXVD2vKlcbSAw1PDcWGCMvTywLUAw5NlcbHy3r1ywXdDxjYzw50lcbYzxrYEufMDgvYlcbZDhjPBMCUzM9YBwf0kcCLlJbMjYWGCMvZzxruAw1Lksb9cMvUzaOkAwyGy3vYCMvUDca8psbSAw1PDcb0AgvUcIaGBg9JywWGCMvTywLUAw5Nid0GBgLTAxqGlsbJDxjYzw50cIaGCMvKAxmUy2fSBcGNse1trvqNlcblrvLtwZfDlcaNy291BNqNlcbZDhjPBMCUzM9YBwf0kcCLlJbMjYWGy3vYCMvUDcKSicD3Aw5KB3DtDgfYDcCSihn0CMLUzY5MB3jTyxqOjYuUmgyNlcb3Aw5KB3DtDgfYDcKPcIaGCMvKAxmUy2fSBcGNuevyueLsrsCSieTfwvnBmv0Sihn0CMLUzY5MB3jTyxqOjYuUmgyNlcbWDhrSksKkicbYzxr1CM4GEYaXlcbSAw1PDcWGCMvTywLUAw5NlcbJDxjYzw50lcaWlcbZDhjPBMCUzM9YBwf0kcCLlJbMjYWGCMvZzxruAw1Lksb9cMvSC2ukicbSB2nHBcbHy3r1ywXdDxjYzw50id0GmaOGigLMihn0B3jLzfDPBMrVDYa9psb3Aw5KB3DtDgfYDcb0AgvUcIaGicbHy3r1ywXdDxjYzw50id0GC3rVCMvKq291BNqkicbLBMqkicbSB2nHBcbYzw1HAw5PBMCGpsbTyxrOlM1HEcGWlcbSAw1PDcaTigfJDhvHBen1CNjLBNqPcIaGBg9JywWGCMv0CNLbzNrLCIa9ig1HDgGUy2vPBcHWDhrSic8GmtaWmc4WkqOGigLMihjLDhj5qwz0zxiGpcaXihrOzw4kicaGihjLDhj5qwz0zxiGpsaXcIaGzw5KcIaGCMv0DxjUihSGmcWGBgLTAxqSihjLBwfPBMLUzYWGywn0DwfSq3vYCMvUDcWGCMv0CNLbzNrLCIWGC3rYAw5NlMzVCM1HDcGNjs4WzICSihjLC2v0vgLTzsKGFqPLBMqk","mMjeDej2yq","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","mtq4otqXwMrhvLn4"];_0x38b4=function(){return _0x5cbfa5};return _0x38b4()}import _0x1f4116 from"crypto";export const fixedWindowScript=_0x53dc29(334);export const slidingWindowLogScript="\nlocal now\nif ARGV[5] and tonumber(ARGV[5]) and tonumber(ARGV[5]) > 0 then\n now = math.floor(tonumber(ARGV[5]))\nelse\n local time_res = redis.call('TIME')\n now = math.floor(tonumber(time_res[1]) * 1000.0 + (tonumber(time_res[2]) / 1000.0))\nend\n\nlocal limit = tonumber(ARGV[1]) * 1.0\nlocal windowMs = tonumber(ARGV[2]) * 1.0\nlocal cost = tonumber(ARGV[3]) * 1.0\nlocal req_id = ARGV[4] or tostring(now)\n\nlocal windowStart = now - windowMs\nredis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', '(' .. string.format('%.0f', windowStart))\n\nlocal current = tonumber(redis.call('ZCARD', KEYS[1])) or 0.0\n\nif cost == 0 then\n local remaining = math.max(0.0, limit - current)\n local oldest = redis.call('ZRANGE', KEYS[1], 0, 0, 'WITHSCORES')\n local resetTime = now + windowMs\n if oldest and #oldest >= 2 and tonumber(oldest[2]) then\n resetTime = tonumber(oldest[2]) + windowMs\n end\n local isAllowed = 1\n local retryAfter = 0\n if current >= limit then\n isAllowed = 0\n local waitMs = resetTime - now\n if waitMs <= 0 then waitMs = 1 end\n retryAfter = math.ceil(waitMs / 1000.0)\n if retryAfter < 1 then retryAfter = 1 end\n end\n return { isAllowed, limit, remaining, current, retryAfter, string.format('%.0f', resetTime) }\nend\n\nif current + cost <= limit then\n for i = 1, cost do\n redis.call('ZADD', KEYS[1], now, req_id .. ':' .. tostring(i) .. ':' .. tostring(math.random(100000, 999999)))\n end\n redis.call('PEXPIRE', KEYS[1], string.format('%.0f', windowMs))\n local consumed = current + cost\n local remaining = limit - consumed\n local oldest = redis.call('ZRANGE', KEYS[1], 0, 0, 'WITHSCORES')\n local resetTime = now + windowMs\n if oldest and #oldest >= 2 and tonumber(oldest[2]) then\n resetTime = tonumber(oldest[2]) + windowMs\n end\n return { 1, limit, remaining, consumed, 0, string.format('%.0f', resetTime) }\nelse\n local targetIdx = math.floor((current + cost) - limit - 1)\n if targetIdx < 0 then\n targetIdx = 0\n end\n if targetIdx >= current then\n targetIdx = math.max(0, math.floor(current - 1))\n end\n local target = redis.call('ZRANGE', KEYS[1], targetIdx, targetIdx, 'WITHSCORES')\n local expireScore = now\n if target and #target >= 2 and tonumber(target[2]) then\n expireScore = tonumber(target[2])\n end\n local resetTime = expireScore + windowMs\n local waitMs = resetTime - now\n if waitMs <= 0 then\n waitMs = 1\n end\n local retryAfter = math.ceil(waitMs / 1000.0)\n if retryAfter < 1 then\n retryAfter = 1\n end\n local remaining = math.max(0.0, limit - current)\n return { 0, limit, remaining, current, retryAfter, string.format('%.0f', resetTime) }\nend\n";export const slidingWindowCounterScript=_0x53dc29(339);export const tokenBucketScript=_0x53dc29(336);export const leakyBucketScript="\nlocal now\nif ARGV[5] and tonumber(ARGV[5]) and tonumber(ARGV[5]) > 0 then\n now = math.floor(tonumber(ARGV[5]))\nelse\n local time_res = redis.call('TIME')\n now = math.floor(tonumber(time_res[1]) * 1000.0 + (tonumber(time_res[2]) / 1000.0))\nend\n\nlocal capacity = tonumber(ARGV[1]) * 1.0\nlocal leakRate = tonumber(ARGV[2]) * 1.0\nlocal leakInterval = tonumber(ARGV[3]) * 1.0\nlocal cost = tonumber(ARGV[4]) * 1.0\n\nlocal rate = leakRate / leakInterval\n\nlocal data = redis.call('HMGET', KEYS[1], 'water', 'lastLeak')\nlocal water = tonumber(data[1])\nlocal lastLeak = tonumber(data[2])\n\nif not water then\n water = 0.0\n lastLeak = now\nelse\n local elapsed = math.max(0.0, now - lastLeak)\n water = math.max(0.0, water - (elapsed * rate))\n lastLeak = now\nend\n\nlocal pexpire = math.ceil((capacity / rate) * 2.0)\nif pexpire < 1000 then\n pexpire = 1000\nend\n\nif cost == 0 then\n local consumed = math.ceil(water)\n local remaining = math.max(0.0, math.floor(capacity - water))\n local resetTime = now + math.ceil(water / rate)\n local isAllowed = 1\n local retryAfter = 0\n if water >= capacity then\n isAllowed = 0\n local waitMs = math.ceil(1.0 / rate)\n retryAfter = math.ceil(waitMs / 1000.0)\n if retryAfter < 1 then retryAfter = 1 end\n end\n redis.call('HMSET', KEYS[1], 'water', tostring(water), 'lastLeak', string.format('%.0f', lastLeak))\n redis.call('PEXPIRE', KEYS[1], string.format('%.0f', pexpire))\n return { isAllowed, capacity, remaining, consumed, retryAfter, string.format('%.0f', resetTime), 0 }\nend\n\nif (water + cost) <= capacity then\n water = water + cost\n local consumed = math.ceil(water)\n local remaining = math.max(0.0, math.floor(capacity - water))\n local resetTime = now + math.ceil(water / rate)\n redis.call('HMSET', KEYS[1], 'water', tostring(water), 'lastLeak', string.format('%.0f', lastLeak))\n redis.call('PEXPIRE', KEYS[1], string.format('%.0f', pexpire))\n return { 1, capacity, remaining, consumed, 0, string.format('%.0f', resetTime), 0 }\nelse\n local consumed = math.ceil(water)\n local remaining = math.max(0.0, math.floor(capacity - water))\n local deficit = (water + cost) - capacity\n local waitMs = math.ceil(deficit / rate)\n local retryAfter = math.ceil(waitMs / 1000.0)\n if retryAfter < 1 then\n retryAfter = 1\n end\n local resetTime = now + math.ceil(water / rate)\n redis.call('HMSET', KEYS[1], 'water', tostring(water), 'lastLeak', string.format('%.0f', lastLeak))\n redis.call('PEXPIRE', KEYS[1], string.format('%.0f', pexpire))\n return { 0, capacity, remaining, consumed, retryAfter, string.format('%.0f', resetTime), waitMs }\nend\n";export const SCRIPTS={"fixed-window":fixedWindowScript,"sliding-window-log":slidingWindowLogScript,"sliding-window-counter":slidingWindowCounterScript,"token-bucket":tokenBucketScript,"leaky-bucket":leakyBucketScript};export const SCRIPT_SHAS=Object["fromEntries"](Object[_0x53dc29(328)](SCRIPTS)["map"](([_0xea548c,_0x2e06ed])=>[_0xea548c,_0x1f4116[_0x53dc29(327)](_0x53dc29(341))[_0x53dc29(332)](_0x2e06ed)["digest"]("hex")]));
1
+ import crypto from'crypto';export const fixedWindowScript=`
2
+ local now
3
+ if ARGV[4] and tonumber(ARGV[4]) and tonumber(ARGV[4]) > 0 then
4
+ now = math.floor(tonumber(ARGV[4]))
5
+ else
6
+ local time_res = redis.call('TIME')
7
+ now = math.floor(tonumber(time_res[1]) * 1000.0 + (tonumber(time_res[2]) / 1000.0))
8
+ end
9
+
10
+ local limit = tonumber(ARGV[1]) * 1.0
11
+ local windowMs = tonumber(ARGV[2]) * 1.0
12
+ local cost = tonumber(ARGV[3]) * 1.0
13
+
14
+ local data = redis.call('HMGET', KEYS[1], 'count', 'windowStart', 'resetTime')
15
+ local storedCount = tonumber(data[1]) or 0
16
+ local storedWindow = tonumber(data[2]) or 0
17
+ local storedReset = tonumber(data[3]) or 0
18
+
19
+ -- The window is anchored on the first request of a key and never slides, so a
20
+ -- client that straddles a wall clock boundary cannot consume two windows in
21
+ -- quick succession.
22
+ local current
23
+ local windowStart
24
+ local resetTime
25
+ if storedReset > now then
26
+ current = storedCount
27
+ windowStart = storedWindow
28
+ resetTime = storedReset
29
+ else
30
+ current = 0
31
+ windowStart = now
32
+ resetTime = now + windowMs
33
+ end
34
+
35
+ local pttl = math.floor(resetTime - now)
36
+ if pttl <= 0 then
37
+ pttl = 1
38
+ end
39
+
40
+ if cost == 0 then
41
+ local remaining = math.max(0, limit - current)
42
+ local isAllowed = 1
43
+ local retryAfter = 0
44
+ if current >= limit then
45
+ isAllowed = 0
46
+ retryAfter = math.ceil(pttl / 1000.0)
47
+ if retryAfter < 1 then retryAfter = 1 end
48
+ end
49
+ return { isAllowed, limit, remaining, current, retryAfter, string.format('%.0f', resetTime) }
50
+ end
51
+
52
+ if current + cost <= limit then
53
+ local nextCount = current + cost
54
+ local remaining = limit - nextCount
55
+ redis.call('HMSET', KEYS[1], 'count', string.format('%.0f', nextCount), 'windowStart', string.format('%.0f', windowStart), 'resetTime', string.format('%.0f', resetTime))
56
+ redis.call('PEXPIRE', KEYS[1], string.format('%.0f', pttl))
57
+ return { 1, limit, remaining, nextCount, 0, string.format('%.0f', resetTime) }
58
+ else
59
+ local remaining = math.max(0, limit - current)
60
+ local retryAfter = math.ceil(pttl / 1000.0)
61
+ if retryAfter < 1 then
62
+ retryAfter = 1
63
+ end
64
+ return { 0, limit, remaining, current, retryAfter, string.format('%.0f', resetTime) }
65
+ end
66
+ `;export const slidingWindowLogScript=`
67
+ local now
68
+ if ARGV[5] and tonumber(ARGV[5]) and tonumber(ARGV[5]) > 0 then
69
+ now = math.floor(tonumber(ARGV[5]))
70
+ else
71
+ local time_res = redis.call('TIME')
72
+ now = math.floor(tonumber(time_res[1]) * 1000.0 + (tonumber(time_res[2]) / 1000.0))
73
+ end
74
+
75
+ local limit = tonumber(ARGV[1]) * 1.0
76
+ local windowMs = tonumber(ARGV[2]) * 1.0
77
+ local cost = tonumber(ARGV[3]) * 1.0
78
+ local req_id = ARGV[4] or tostring(now)
79
+
80
+ local windowStart = now - windowMs
81
+ redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', '(' .. string.format('%.0f', windowStart))
82
+
83
+ local current = tonumber(redis.call('ZCARD', KEYS[1])) or 0.0
84
+
85
+ if cost == 0 then
86
+ local remaining = math.max(0.0, limit - current)
87
+ local oldest = redis.call('ZRANGE', KEYS[1], 0, 0, 'WITHSCORES')
88
+ local resetTime = now + windowMs
89
+ if oldest and #oldest >= 2 and tonumber(oldest[2]) then
90
+ resetTime = tonumber(oldest[2]) + windowMs
91
+ end
92
+ local isAllowed = 1
93
+ local retryAfter = 0
94
+ if current >= limit then
95
+ isAllowed = 0
96
+ local waitMs = resetTime - now
97
+ if waitMs <= 0 then waitMs = 1 end
98
+ retryAfter = math.ceil(waitMs / 1000.0)
99
+ if retryAfter < 1 then retryAfter = 1 end
100
+ end
101
+ return { isAllowed, limit, remaining, current, retryAfter, string.format('%.0f', resetTime) }
102
+ end
103
+
104
+ if current + cost <= limit then
105
+ for i = 1, cost do
106
+ redis.call('ZADD', KEYS[1], now, req_id .. ':' .. tostring(i) .. ':' .. tostring(math.random(100000, 999999)))
107
+ end
108
+ redis.call('PEXPIRE', KEYS[1], string.format('%.0f', windowMs))
109
+ local consumed = current + cost
110
+ local remaining = limit - consumed
111
+ local oldest = redis.call('ZRANGE', KEYS[1], 0, 0, 'WITHSCORES')
112
+ local resetTime = now + windowMs
113
+ if oldest and #oldest >= 2 and tonumber(oldest[2]) then
114
+ resetTime = tonumber(oldest[2]) + windowMs
115
+ end
116
+ return { 1, limit, remaining, consumed, 0, string.format('%.0f', resetTime) }
117
+ else
118
+ local targetIdx = math.floor((current + cost) - limit - 1)
119
+ if targetIdx < 0 then
120
+ targetIdx = 0
121
+ end
122
+ if targetIdx >= current then
123
+ targetIdx = math.max(0, math.floor(current - 1))
124
+ end
125
+ local target = redis.call('ZRANGE', KEYS[1], targetIdx, targetIdx, 'WITHSCORES')
126
+ local expireScore = now
127
+ if target and #target >= 2 and tonumber(target[2]) then
128
+ expireScore = tonumber(target[2])
129
+ end
130
+ local resetTime = expireScore + windowMs
131
+ local waitMs = resetTime - now
132
+ if waitMs <= 0 then
133
+ waitMs = 1
134
+ end
135
+ local retryAfter = math.ceil(waitMs / 1000.0)
136
+ if retryAfter < 1 then
137
+ retryAfter = 1
138
+ end
139
+ local remaining = math.max(0.0, limit - current)
140
+ return { 0, limit, remaining, current, retryAfter, string.format('%.0f', resetTime) }
141
+ end
142
+ `;export const slidingWindowCounterScript=`
143
+ local now
144
+ if ARGV[4] and tonumber(ARGV[4]) and tonumber(ARGV[4]) > 0 then
145
+ now = math.floor(tonumber(ARGV[4]))
146
+ else
147
+ local time_res = redis.call('TIME')
148
+ now = math.floor(tonumber(time_res[1]) * 1000.0 + (tonumber(time_res[2]) / 1000.0))
149
+ end
150
+
151
+ local limit = tonumber(ARGV[1]) * 1.0
152
+ local windowMs = tonumber(ARGV[2]) * 1.0
153
+ local cost = tonumber(ARGV[3]) * 1.0
154
+
155
+ local currWindowStart = math.floor(now / windowMs) * windowMs
156
+ local resetTime = currWindowStart + windowMs
157
+
158
+ local data = redis.call('HMGET', KEYS[1], 'windowStart', 'prevCount', 'currCount')
159
+ local storedWindow = tonumber(data[1])
160
+ local prevCount = tonumber(data[2]) or 0.0
161
+ local currCount = tonumber(data[3]) or 0.0
162
+
163
+ if not storedWindow then
164
+ storedWindow = currWindowStart
165
+ prevCount = 0.0
166
+ currCount = 0.0
167
+ elseif currWindowStart == storedWindow then
168
+ -- same window
169
+ elseif currWindowStart == (storedWindow + windowMs) then
170
+ prevCount = currCount
171
+ currCount = 0.0
172
+ storedWindow = currWindowStart
173
+ else
174
+ prevCount = 0.0
175
+ currCount = 0.0
176
+ storedWindow = currWindowStart
177
+ end
178
+
179
+ local elapsed = now - currWindowStart
180
+ local weight = math.max(0.0, 1.0 - (elapsed / windowMs))
181
+ local estimated = (prevCount * weight) + currCount
182
+
183
+ if cost == 0 then
184
+ local consumed = math.floor(estimated + 0.5)
185
+ local remaining = math.max(0.0, limit - consumed)
186
+ local isAllowed = 1
187
+ local retryAfter = 0
188
+ if estimated >= limit then
189
+ isAllowed = 0
190
+ local waitMs = resetTime - now
191
+ if prevCount > 0 then
192
+ local neededWeight = (limit - currCount) / prevCount
193
+ if neededWeight < 1.0 and neededWeight >= 0.0 then
194
+ local t = windowMs * (1.0 - neededWeight)
195
+ waitMs = math.max(1.0, math.ceil(t - elapsed))
196
+ end
197
+ end
198
+ if waitMs <= 0 or waitMs > windowMs then
199
+ waitMs = resetTime - now
200
+ end
201
+ retryAfter = math.ceil(waitMs / 1000.0)
202
+ if retryAfter < 1 then retryAfter = 1 end
203
+ end
204
+ return { isAllowed, limit, remaining, consumed, retryAfter, string.format('%.0f', resetTime) }
205
+ end
206
+
207
+ if (estimated + cost) <= limit then
208
+ currCount = currCount + cost
209
+ local consumed = math.floor(estimated + cost + 0.5)
210
+ local remaining = math.max(0.0, limit - consumed)
211
+ redis.call('HMSET', KEYS[1], 'windowStart', string.format('%.0f', storedWindow), 'prevCount', string.format('%.0f', prevCount), 'currCount', string.format('%.0f', currCount))
212
+ redis.call('PEXPIRE', KEYS[1], string.format('%.0f', windowMs * 2.0))
213
+ return { 1, limit, remaining, consumed, 0, string.format('%.0f', resetTime) }
214
+ else
215
+ local consumed = math.floor(estimated + 0.5)
216
+ local remaining = math.max(0.0, limit - consumed)
217
+ local waitMs = resetTime - now
218
+ if prevCount > 0 then
219
+ local neededWeight = (limit - currCount - cost) / prevCount
220
+ if neededWeight < 1.0 and neededWeight >= 0.0 then
221
+ local t = windowMs * (1.0 - neededWeight)
222
+ waitMs = math.max(1.0, math.ceil(t - elapsed))
223
+ end
224
+ end
225
+ if waitMs <= 0 or waitMs > windowMs then
226
+ waitMs = resetTime - now
227
+ end
228
+ local retryAfter = math.ceil(waitMs / 1000.0)
229
+ if retryAfter < 1 then
230
+ retryAfter = 1
231
+ end
232
+ redis.call('HMSET', KEYS[1], 'windowStart', string.format('%.0f', storedWindow), 'prevCount', string.format('%.0f', prevCount), 'currCount', string.format('%.0f', currCount))
233
+ redis.call('PEXPIRE', KEYS[1], string.format('%.0f', windowMs * 2.0))
234
+ return { 0, limit, remaining, consumed, retryAfter, string.format('%.0f', resetTime) }
235
+ end
236
+ `;export const tokenBucketScript=`
237
+ local now
238
+ if ARGV[6] and tonumber(ARGV[6]) and tonumber(ARGV[6]) > 0 then
239
+ now = math.floor(tonumber(ARGV[6]))
240
+ else
241
+ local time_res = redis.call('TIME')
242
+ now = math.floor(tonumber(time_res[1]) * 1000.0 + (tonumber(time_res[2]) / 1000.0))
243
+ end
244
+
245
+ local capacity = tonumber(ARGV[1]) * 1.0
246
+ local refillRate = tonumber(ARGV[2]) * 1.0
247
+ local refillInterval = tonumber(ARGV[3]) * 1.0
248
+ local cost = tonumber(ARGV[4]) * 1.0
249
+ local initialTokens = (tonumber(ARGV[5]) or capacity) * 1.0
250
+
251
+ local rate = refillRate / refillInterval
252
+
253
+ local data = redis.call('HMGET', KEYS[1], 'tokens', 'lastRefill')
254
+ local tokens = tonumber(data[1]) or initialTokens
255
+ local lastRefill = tonumber(data[2]) or now
256
+
257
+ local elapsed = math.max(0.0, now - lastRefill)
258
+ tokens = math.min(capacity, tokens + (elapsed * rate))
259
+ lastRefill = now
260
+
261
+ local pexpire = math.ceil((capacity / rate) * 2.0)
262
+ if pexpire < 1000 then
263
+ pexpire = 1000
264
+ end
265
+
266
+ if cost == 0 then
267
+ local consumed = capacity - math.floor(tokens)
268
+ local remaining = math.floor(tokens)
269
+ local resetTime = now + math.ceil((capacity - tokens) / rate)
270
+ local isAllowed = 1
271
+ local retryAfter = 0
272
+ if tokens < 1.0 then
273
+ isAllowed = 0
274
+ local deficit = 1.0 - tokens
275
+ local waitMs = math.ceil(deficit / rate)
276
+ retryAfter = math.ceil(waitMs / 1000.0)
277
+ if retryAfter < 1 then retryAfter = 1 end
278
+ end
279
+ redis.call('HMSET', KEYS[1], 'tokens', tostring(tokens), 'lastRefill', string.format('%.0f', lastRefill))
280
+ redis.call('PEXPIRE', KEYS[1], string.format('%.0f', pexpire))
281
+ return { isAllowed, capacity, remaining, consumed, retryAfter, string.format('%.0f', resetTime) }
282
+ end
283
+
284
+ if tokens >= cost then
285
+ tokens = tokens - cost
286
+ local consumed = capacity - math.floor(tokens)
287
+ local remaining = math.floor(tokens)
288
+ local resetTime = now + math.ceil((capacity - tokens) / rate)
289
+ redis.call('HMSET', KEYS[1], 'tokens', tostring(tokens), 'lastRefill', string.format('%.0f', lastRefill))
290
+ redis.call('PEXPIRE', KEYS[1], string.format('%.0f', pexpire))
291
+ return { 1, capacity, remaining, consumed, 0, string.format('%.0f', resetTime) }
292
+ else
293
+ local consumed = capacity - math.floor(tokens)
294
+ local remaining = math.floor(tokens)
295
+ local deficit = cost - tokens
296
+ local waitMs = math.ceil(deficit / rate)
297
+ local retryAfter = math.ceil(waitMs / 1000.0)
298
+ if retryAfter < 1 then
299
+ retryAfter = 1
300
+ end
301
+ local resetTime = now + math.ceil((capacity - tokens) / rate)
302
+ redis.call('HMSET', KEYS[1], 'tokens', tostring(tokens), 'lastRefill', string.format('%.0f', lastRefill))
303
+ redis.call('PEXPIRE', KEYS[1], string.format('%.0f', pexpire))
304
+ return { 0, capacity, remaining, consumed, retryAfter, string.format('%.0f', resetTime) }
305
+ end
306
+ `;export const leakyBucketScript=`
307
+ local now
308
+ if ARGV[5] and tonumber(ARGV[5]) and tonumber(ARGV[5]) > 0 then
309
+ now = math.floor(tonumber(ARGV[5]))
310
+ else
311
+ local time_res = redis.call('TIME')
312
+ now = math.floor(tonumber(time_res[1]) * 1000.0 + (tonumber(time_res[2]) / 1000.0))
313
+ end
314
+
315
+ local capacity = tonumber(ARGV[1]) * 1.0
316
+ local leakRate = tonumber(ARGV[2]) * 1.0
317
+ local leakInterval = tonumber(ARGV[3]) * 1.0
318
+ local cost = tonumber(ARGV[4]) * 1.0
319
+
320
+ local rate = leakRate / leakInterval
321
+
322
+ local data = redis.call('HMGET', KEYS[1], 'water', 'lastLeak')
323
+ local water = tonumber(data[1])
324
+ local lastLeak = tonumber(data[2])
325
+
326
+ if not water then
327
+ water = 0.0
328
+ lastLeak = now
329
+ else
330
+ local elapsed = math.max(0.0, now - lastLeak)
331
+ water = math.max(0.0, water - (elapsed * rate))
332
+ lastLeak = now
333
+ end
334
+
335
+ local pexpire = math.ceil((capacity / rate) * 2.0)
336
+ if pexpire < 1000 then
337
+ pexpire = 1000
338
+ end
339
+
340
+ if cost == 0 then
341
+ local consumed = math.ceil(water)
342
+ local remaining = math.max(0.0, math.floor(capacity - water))
343
+ local resetTime = now + math.ceil(water / rate)
344
+ local isAllowed = 1
345
+ local retryAfter = 0
346
+ if water >= capacity then
347
+ isAllowed = 0
348
+ local waitMs = math.ceil(1.0 / rate)
349
+ retryAfter = math.ceil(waitMs / 1000.0)
350
+ if retryAfter < 1 then retryAfter = 1 end
351
+ end
352
+ redis.call('HMSET', KEYS[1], 'water', tostring(water), 'lastLeak', string.format('%.0f', lastLeak))
353
+ redis.call('PEXPIRE', KEYS[1], string.format('%.0f', pexpire))
354
+ return { isAllowed, capacity, remaining, consumed, retryAfter, string.format('%.0f', resetTime), 0 }
355
+ end
356
+
357
+ if (water + cost) <= capacity then
358
+ water = water + cost
359
+ local consumed = math.ceil(water)
360
+ local remaining = math.max(0.0, math.floor(capacity - water))
361
+ local resetTime = now + math.ceil(water / rate)
362
+ redis.call('HMSET', KEYS[1], 'water', tostring(water), 'lastLeak', string.format('%.0f', lastLeak))
363
+ redis.call('PEXPIRE', KEYS[1], string.format('%.0f', pexpire))
364
+ return { 1, capacity, remaining, consumed, 0, string.format('%.0f', resetTime), 0 }
365
+ else
366
+ local consumed = math.ceil(water)
367
+ local remaining = math.max(0.0, math.floor(capacity - water))
368
+ local deficit = (water + cost) - capacity
369
+ local waitMs = math.ceil(deficit / rate)
370
+ local retryAfter = math.ceil(waitMs / 1000.0)
371
+ if retryAfter < 1 then
372
+ retryAfter = 1
373
+ end
374
+ local resetTime = now + math.ceil(water / rate)
375
+ redis.call('HMSET', KEYS[1], 'water', tostring(water), 'lastLeak', string.format('%.0f', lastLeak))
376
+ redis.call('PEXPIRE', KEYS[1], string.format('%.0f', pexpire))
377
+ return { 0, capacity, remaining, consumed, retryAfter, string.format('%.0f', resetTime), waitMs }
378
+ end
379
+ `;export const SCRIPTS={'fixed-window':fixedWindowScript,'sliding-window-log':slidingWindowLogScript,'sliding-window-counter':slidingWindowCounterScript,'token-bucket':tokenBucketScript,'leaky-bucket':leakyBucketScript};export const SCRIPT_SHAS=Object.fromEntries(Object.entries(SCRIPTS).map(([name,script])=>[name,crypto.createHash('sha1').update(script).digest('hex')]));
@@ -1 +1 @@
1
- const _0x3a7b51=_0x1fd1;(function(_0x1628fd,_0x196bdf){const _0x4bec21=_0x1fd1,_0x2e1cef=_0x1628fd();while(!![]){try{const _0x2d0fd3=-parseInt(_0x4bec21(258))/1+parseInt(_0x4bec21(248))/2*(-parseInt(_0x4bec21(272))/3)+parseInt(_0x4bec21(284))/4+-parseInt(_0x4bec21(262))/5*(-parseInt(_0x4bec21(281))/6)+parseInt(_0x4bec21(250))/7*(parseInt(_0x4bec21(275))/8)+-parseInt(_0x4bec21(264))/9*(parseInt(_0x4bec21(261))/10)+parseInt(_0x4bec21(255))/11*(-parseInt(_0x4bec21(274))/12);if(_0x2d0fd3===_0x196bdf)break;else _0x2e1cef["push"](_0x2e1cef["shift"]())}catch(_0x454a71){_0x2e1cef["push"](_0x2e1cef["shift"]())}}})(_0x21d0,512723);import{BaseStore}from"./baseStore.js";class MinHeap{constructor(){const _0x528d0b=_0x1fd1;this[_0x528d0b(246)]=[]}[_0x3a7b51(268)](){const _0x252891=_0x3a7b51;return this[_0x252891(246)]["length"]}[_0x3a7b51(245)](){const _0xe686f0=_0x3a7b51;return this[_0xe686f0(246)][0]||null}["push"](_0x357834){const _0x4648d4=_0x3a7b51;this[_0x4648d4(246)][_0x4648d4(279)](_0x357834),this["_bubbleUp"](this[_0x4648d4(246)][_0x4648d4(249)]-1)}["pop"](){const _0x57d38e=_0x3a7b51;if(this[_0x57d38e(246)][_0x57d38e(249)]===0)return null;const _0x3e0cbb=this[_0x57d38e(246)][0],_0x57cd89=this[_0x57d38e(246)][_0x57d38e(253)]();return this[_0x57d38e(246)]["length"]>0&&(this[_0x57d38e(246)][0]=_0x57cd89,this[_0x57d38e(280)](0)),_0x3e0cbb}[_0x3a7b51(257)](_0x4c6c74){const _0x3b45fa=_0x3a7b51,_0x4991c6=this[_0x3b45fa(246)][_0x4c6c74];while(_0x4c6c74>0){const _0x2bcf81=Math["floor"]((_0x4c6c74-1)/2),_0x59908c=this[_0x3b45fa(246)][_0x2bcf81];if(_0x4991c6["expiresAt"]>=_0x59908c[_0x3b45fa(273)])break;this[_0x3b45fa(246)][_0x4c6c74]=_0x59908c,this["heap"][_0x2bcf81]=_0x4991c6,_0x4c6c74=_0x2bcf81}}["_sinkDown"](_0x199bf2){const _0x2a62ad=_0x3a7b51,_0x2a038e=this[_0x2a62ad(246)][_0x2a62ad(249)],_0x2190e4=this["heap"][_0x199bf2];while(!![]){const _0xa70e16=2*_0x199bf2+1,_0xb94c3d=2*_0x199bf2+2;let _0x2d94c9=null;_0xa70e16<_0x2a038e&&this[_0x2a62ad(246)][_0xa70e16][_0x2a62ad(273)]<_0x2190e4[_0x2a62ad(273)]&&(_0x2d94c9=_0xa70e16);_0xb94c3d<_0x2a038e&&(_0x2d94c9===null&&this[_0x2a62ad(246)][_0xb94c3d][_0x2a62ad(273)]<_0x2190e4["expiresAt"]||_0x2d94c9!==null&&this["heap"][_0xb94c3d][_0x2a62ad(273)]<this[_0x2a62ad(246)][_0xa70e16]["expiresAt"])&&(_0x2d94c9=_0xb94c3d);if(_0x2d94c9===null)break;this[_0x2a62ad(246)][_0x199bf2]=this[_0x2a62ad(246)][_0x2d94c9],this[_0x2a62ad(246)][_0x2d94c9]=_0x2190e4,_0x199bf2=_0x2d94c9}}[_0x3a7b51(254)](){this["heap"]=[]}}class ExpirationTracker{constructor(_0x23cc19={}){const _0x45aeae=_0x3a7b51;this[_0x45aeae(246)]=new MinHeap,this[_0x45aeae(282)]=_0x23cc19["cleanupIntervalMs"]||5000,this[_0x45aeae(260)]=null}["start"](_0x2c5511){const _0x38909b=_0x3a7b51;if(this["timer"])return;this[_0x38909b(260)]=setInterval(()=>{this["purgeExpired"](Date["now"](),_0x2c5511)},this[_0x38909b(282)]),this[_0x38909b(260)][_0x38909b(265)]&&this[_0x38909b(260)]["unref"]()}["stop"](){const _0x2aa003=_0x3a7b51;this[_0x2aa003(260)]&&(clearInterval(this["timer"]),this[_0x2aa003(260)]=null)}["schedule"](_0x189fc3,_0x10236a){const _0x1a6713=_0x3a7b51;this[_0x1a6713(246)]["push"]({"key":_0x189fc3,"expiresAt":_0x10236a})}[_0x3a7b51(285)](_0xe4224d,_0x11679d){const _0x435518=_0x3a7b51;while(this[_0x435518(246)][_0x435518(268)]()>0){const _0x1259e4=this["heap"][_0x435518(245)]();if(!_0x1259e4||_0x1259e4[_0x435518(273)]>_0xe4224d)break;this[_0x435518(246)]["pop"](),_0x11679d&&_0x11679d(_0x1259e4[_0x435518(278)],_0x1259e4[_0x435518(273)])}}["clear"](){const _0x2f8a11=_0x3a7b51;this[_0x2f8a11(246)][_0x2f8a11(254)]()}}function _0x21d0(){const _0x81299=["C2v0","zgvSzxrL","odyYotm1q09pBwfQ","zxHWAxjLC0f0","mtjtvefMwwG","ofb1rLz4BW","C3rHCNq","y2XVC2u","A2v5","ChvZAa","x3nPBMTeB3DU","nMD4tfbqrG","y2XLyw51CeLUDgvYDMfStxm","ywnJzxnZq291BNrLCG","mtiXmdi2nhnjt2HUvG","ChvYz2vfEhbPCMvK","CgvLAW","AgvHCa","zw50CMLLCW","mKTWExbcAW","BgvUz3rO","ndi3ndK3n0HrsuTHAa","z2v0","Bwf4rw50CMLLCW","Cg9W","y2XLyxi","mJuYntG5n1nmEfDKAq","BM93","x2j1yMjSzvvW","mZeWmtaZzM9dtLvb","zgf0yq","DgLTzxi","nZbMEfDhveW","mZm2mdi2mfrhA25ABq","BgfZDefJy2vZCW","mZe1mJK3A1rosxP1","Dw5Yzwy","C2nOzwr1Bgu","C3rVCa","C2L6zq","DhjHy2TLCG"];_0x21d0=function(){return _0x81299};return _0x21d0()}function _0x1fd1(_0x5af6c8,_0x5034e1){_0x5af6c8=_0x5af6c8-245;const _0x21d0fb=_0x21d0();let _0x1fd19c=_0x21d0fb[_0x5af6c8];if(_0x1fd1["lVbyIi"]===undefined){var _0x5e1459=function(_0x247d46){const _0x40f062="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=";let _0x2b9126="",_0x357834="";for(let _0x3e0cbb=0,_0x57cd89,_0x4c6c74,_0x4991c6=0;_0x4c6c74=_0x247d46["charAt"](_0x4991c6++);~_0x4c6c74&&(_0x57cd89=_0x3e0cbb%4?_0x57cd89*64+_0x4c6c74:_0x4c6c74,_0x3e0cbb++%4)?_0x2b9126+=String["fromCharCode"](255&_0x57cd89>>(-2*_0x3e0cbb&6)):0){_0x4c6c74=_0x40f062["indexOf"](_0x4c6c74)}for(let _0x2bcf81=0,_0x59908c=_0x2b9126["length"];_0x2bcf81<_0x59908c;_0x2bcf81++){_0x357834+="%"+("00"+_0x2b9126["charCodeAt"](_0x2bcf81)["toString"](16))["slice"](-2)}return decodeURIComponent(_0x357834)};_0x1fd1["BxmjiD"]=_0x5e1459,_0x1fd1["FbytnR"]={},_0x1fd1["lVbyIi"]=!![]}const _0x4dd795=_0x21d0fb[0];_0x1fd1["rhRlmd"]!==_0x4dd795&&(_0x1fd1["FbytnR"]={},_0x1fd1["rhRlmd"]=_0x4dd795);const _0x56fb35=_0x1fd1["FbytnR"][_0x5af6c8];return _0x56fb35===undefined?(_0x1fd19c=_0x1fd1["BxmjiD"](_0x1fd19c),_0x1fd1["FbytnR"][_0x5af6c8]=_0x1fd19c):_0x1fd19c=_0x56fb35,_0x1fd19c}export class MemoryStore extends BaseStore{constructor(_0x30464a={}){const _0xbbd713=_0x3a7b51;super(),this["maxEntries"]=_0x30464a[_0xbbd713(252)]||10000,this[_0xbbd713(282)]=_0x30464a[_0xbbd713(282)]||5000,this[_0xbbd713(259)]=new Map,this[_0xbbd713(283)]=0,this[_0xbbd713(269)]=new ExpirationTracker({"cleanupIntervalMs":this[_0xbbd713(282)]}),this[_0xbbd713(269)][_0xbbd713(276)](_0x1ed340=>{const _0x218683=_0xbbd713,_0x59fe78=this[_0x218683(259)]["get"](_0x1ed340);_0x59fe78&&_0x59fe78[_0x218683(273)]<=Date[_0x218683(256)]()&&this[_0x218683(259)][_0x218683(271)](_0x1ed340)})}async[_0x3a7b51(251)](_0x5a50f3){const _0x4ba823=_0x3a7b51,_0x552595=this["data"][_0x4ba823(251)](_0x5a50f3);if(!_0x552595)return null;if(_0x552595[_0x4ba823(273)]&&_0x552595[_0x4ba823(273)]<=Date[_0x4ba823(256)]())return this["data"][_0x4ba823(271)](_0x5a50f3),null;return _0x552595[_0x4ba823(263)]=++this[_0x4ba823(283)],_0x552595["value"]}async["set"](_0x1e5b47,_0x392e89,_0x3d7217){const _0x29ff00=_0x3a7b51,_0x13195b=Date["now"](),_0x52136f=_0x3d7217&&_0x3d7217>0?_0x13195b+_0x3d7217:null;if(this[_0x29ff00(259)][_0x29ff00(268)]>=this[_0x29ff00(252)]&&!this[_0x29ff00(259)]["has"](_0x1e5b47)){this["tracker"][_0x29ff00(285)](_0x13195b,_0x4d236b=>{const _0x30a3fd=_0x29ff00,_0x5a201b=this[_0x30a3fd(259)][_0x30a3fd(251)](_0x4d236b);_0x5a201b&&_0x5a201b[_0x30a3fd(273)]<=_0x13195b&&this[_0x30a3fd(259)]["delete"](_0x4d236b)});if(this[_0x29ff00(259)]["size"]>=this[_0x29ff00(252)]){let _0x4ecf1f=null,_0x3b6348=Infinity;for(const[_0x296c5a,_0x1a77c4]of this[_0x29ff00(259)][_0x29ff00(247)]()){_0x1a77c4[_0x29ff00(263)]<_0x3b6348&&(_0x3b6348=_0x1a77c4[_0x29ff00(263)],_0x4ecf1f=_0x296c5a)}_0x4ecf1f!==null&&this[_0x29ff00(259)]["delete"](_0x4ecf1f)}}return this[_0x29ff00(259)][_0x29ff00(270)](_0x1e5b47,{"value":_0x392e89,"expiresAt":_0x52136f,"lastAccess":++this[_0x29ff00(283)]}),_0x52136f&&this["tracker"][_0x29ff00(266)](_0x1e5b47,_0x52136f),!![]}async[_0x3a7b51(271)](_0x1b4780){const _0x3a013e=_0x3a7b51;return this["data"][_0x3a013e(271)](_0x1b4780)}async[_0x3a7b51(254)](){const _0x2b1155=_0x3a7b51;this[_0x2b1155(259)][_0x2b1155(254)](),this[_0x2b1155(269)]["clear"]()}async[_0x3a7b51(277)](){const _0xd21582=_0x3a7b51;this[_0xd21582(269)][_0xd21582(267)](),this[_0xd21582(259)][_0xd21582(254)]()}[_0x3a7b51(268)](){const _0x288e7e=_0x3a7b51;return this[_0x288e7e(259)][_0x288e7e(268)]}}export default MemoryStore;
1
+ import{BaseStore}from'./baseStore.js';class MinHeap{constructor(){this.heap=[];}size(){return this.heap.length;}peek(){return this.heap[0]||null;}push(item){this.heap.push(item);this._bubbleUp(this.heap.length-1);}pop(){if(this.heap.length===0)return null;const top=this.heap[0];const bottom=this.heap.pop();if(this.heap.length>0){this.heap[0]=bottom;this._sinkDown(0);}return top;}_bubbleUp(index){const item=this.heap[index];while(index>0){const parentIdx=Math.floor((index-1)/2);const parent=this.heap[parentIdx];if(item.expiresAt>=parent.expiresAt)break;this.heap[index]=parent;this.heap[parentIdx]=item;index=parentIdx;}}_sinkDown(index){const length=this.heap.length;const item=this.heap[index];while(true){const leftIdx=2*index+1;const rightIdx=2*index+2;let swapIdx=null;if(leftIdx<length&&this.heap[leftIdx].expiresAt<item.expiresAt){swapIdx=leftIdx;}if(rightIdx<length){if(swapIdx===null&&this.heap[rightIdx].expiresAt<item.expiresAt||swapIdx!==null&&this.heap[rightIdx].expiresAt<this.heap[leftIdx].expiresAt){swapIdx=rightIdx;}}if(swapIdx===null)break;this.heap[index]=this.heap[swapIdx];this.heap[swapIdx]=item;index=swapIdx;}}clear(){this.heap=[];}}class ExpirationTracker{constructor(options={}){this.heap=new MinHeap();this.cleanupIntervalMs=options.cleanupIntervalMs||5000;this.timer=null;}start(onExpire){if(this.timer)return;this.timer=setInterval(()=>{this.purgeExpired(Date.now(),onExpire);},this.cleanupIntervalMs);if(this.timer.unref){this.timer.unref();}}stop(){if(this.timer){clearInterval(this.timer);this.timer=null;}}schedule(key,expiresAt){this.heap.push({key,expiresAt});}purgeExpired(now,onExpire){while(this.heap.size()>0){const top=this.heap.peek();if(!top||top.expiresAt>now){break;}this.heap.pop();if(onExpire){onExpire(top.key,top.expiresAt);}}}clear(){this.heap.clear();}}export class MemoryStore extends BaseStore{constructor(options={}){super();this.maxEntries=options.maxEntries||10000;this.cleanupIntervalMs=options.cleanupIntervalMs||5000;this.data=new Map();this.tracker=new ExpirationTracker({cleanupIntervalMs:this.cleanupIntervalMs});this.tracker.start(key=>{const entry=this.data.get(key);if(entry&&entry.expiresAt<=Date.now()){this.data.delete(key);}});}async get(key){const entry=this.data.get(key);if(!entry)return null;if(entry.expiresAt&&entry.expiresAt<=Date.now()){this.data.delete(key);return null;}this.data.delete(key);this.data.set(key,entry);return entry.value;}async set(key,value,ttlMs){const now=Date.now();const expiresAt=ttlMs&&ttlMs>0?now+ttlMs:null;const existing=this.data.get(key);const isNew=existing===undefined;if(isNew&&this.data.size>=this.maxEntries){this.tracker.purgeExpired(now,expiredKey=>{const item=this.data.get(expiredKey);if(item&&item.expiresAt<=now){this.data.delete(expiredKey);}});if(this.data.size>=this.maxEntries){for(const oldestKey of this.data.keys()){this.data.delete(oldestKey);break;}}}this.data.delete(key);this.data.set(key,{value,expiresAt});if(expiresAt&&(isNew||existing.expiresAt!==expiresAt)){this.tracker.schedule(key,expiresAt);}return true;}async delete(key){return this.data.delete(key);}async clear(){this.data.clear();this.tracker.clear();}async close(){this.tracker.stop();this.data.clear();}size(){return this.data.size;}}export default MemoryStore;
@@ -1 +1 @@
1
- const _0x5285a6=_0x3abe;(function(_0x1693d8,_0x35ab96){const _0xd2cb9b=_0x3abe,_0x37d2cd=_0x1693d8();while(!![]){try{const _0x5c73b4=parseInt(_0xd2cb9b(206))/1+-parseInt(_0xd2cb9b(190))/2+-parseInt(_0xd2cb9b(143))/3+-parseInt(_0xd2cb9b(164))/4+parseInt(_0xd2cb9b(141))/5+parseInt(_0xd2cb9b(197))/6*(parseInt(_0xd2cb9b(156))/7)+parseInt(_0xd2cb9b(181))/8;if(_0x5c73b4===_0x35ab96)break;else _0x37d2cd["push"](_0x37d2cd["shift"]())}catch(_0x5a235d){_0x37d2cd["push"](_0x37d2cd["shift"]())}}})(_0x163c,139662);import{createRequire}from"module";function _0x3abe(_0xe757fc,_0x52c8bb){_0xe757fc=_0xe757fc-135;const _0x163cbd=_0x163c();let _0x3abee0=_0x163cbd[_0xe757fc];if(_0x3abe["MsDhQP"]===undefined){var _0x257efc=function(_0xf82ef5){const _0x7709de="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=";let _0x2bc285="",_0x48d94e="";for(let _0x19f609=0,_0x15ba6f,_0x343464,_0x4c17ea=0;_0x343464=_0xf82ef5["charAt"](_0x4c17ea++);~_0x343464&&(_0x15ba6f=_0x19f609%4?_0x15ba6f*64+_0x343464:_0x343464,_0x19f609++%4)?_0x2bc285+=String["fromCharCode"](255&_0x15ba6f>>(-2*_0x19f609&6)):0){_0x343464=_0x7709de["indexOf"](_0x343464)}for(let _0x3411b1=0,_0x342c8b=_0x2bc285["length"];_0x3411b1<_0x342c8b;_0x3411b1++){_0x48d94e+="%"+("00"+_0x2bc285["charCodeAt"](_0x3411b1)["toString"](16))["slice"](-2)}return decodeURIComponent(_0x48d94e)};_0x3abe["urSASd"]=_0x257efc,_0x3abe["aJOWaM"]={},_0x3abe["MsDhQP"]=!![]}const _0x3a01d9=_0x163cbd[0];_0x3abe["NgbrQc"]!==_0x3a01d9&&(_0x3abe["aJOWaM"]={},_0x3abe["NgbrQc"]=_0x3a01d9);const _0x3670fc=_0x3abe["aJOWaM"][_0xe757fc];return _0x3670fc===undefined?(_0x3abee0=_0x3abe["urSASd"](_0x3abee0),_0x3abe["aJOWaM"][_0xe757fc]=_0x3abee0):_0x3abee0=_0x3670fc,_0x3abee0}function _0x163c(){const _0x4e0487=["uMvKAxmGy2XLyxiGzxjYB3i6ia","CgfYC2u","C2v0","BgvUz3rO","AxnjBNrLCM5HBenSAwvUDa","rvzbta","Aw5JBhvKzxm","C3rHDhvZ","zNvUy3rPB24","nZC2mZCWsLvRBgT1","zgLZy29UBMvJDa","mZuXmdu0u2virKjK","uMvKAxmGzgvSigvYCM9YoIa","uMvKAxmGy2XPzw50igLZig5VDcbJB25MAwD1CMvKig9Yigf2ywLSywjSzs4GugXLyxnLigLUC3rHBgWGiMLVCMvKAxmIig9YicjYzwrPCYiSig9YihbYB3zPzguGyw4Gywn0AxzLignSAwvUDcbPBNn0yw5Jzsb2AweGDgHLicjJBgLLBNqIig9WDgLVBI4","zw5K","y29UC3rYDwn0B3i","C2vUzenVBw1HBMq","BwfW","zgvS","CMW6","BMfTzq","zMfPBe9Wzw4","A2v5CW","uMvKAxmGz2v0igvYCM9YoIa","mtCYnJLKAxj5uxm","AxndB25Uzwn0zwq","z2v0tM93","y3jLyxrLq2XPzw50","tK9tq1jjufq","y2XPzw50","A2v5uhjLzML4","s0vzuW","nJGWnZuYBgD3wgHO","zgf0yq","AxnszwfKEq","Aw9YzwrPCW","zxzHBhnOyq","C2nYAxb0CW","B25fCNjVCG","AxnnB2nR","AxnpCgvU","zxzHBa","uMvKAxmGy2XPzw50igrVzxmGBM90ihn1ChbVCNqGzxzHBcWGzxzHBhnOysWGB3iGC2vUzenVBw1HBMq","zgvMyxvSDa","BM93","CNvUu2nYAxb0","uMvKAxm","BwvZC2fNzq","zxjYB3i","mtaWndiWofnsB0jQrG","x1jLzgLZtw9JAW","C3rVCMvqCMvMAxG","ChjLzML4","y29UBMvJDa","y2f0y2G","CMvHzhK","DxjS","CxvPDa","mtu3mdG4twTHsLDt","thvHihnJCMLWDcaI","B2jQzwn0","x3bYzwzPEeTLEq","y2XLyxi","r0vu","C2nYAxb0u2HHCW","mtG2sKnbvK1z","rvzbtfniqq","u0vu","z2v0","CMvKAxm","uMvKAxnnB2nR","DxnLuMvKAxnuAw1L","x2LUAxrdBgLLBNq","C3rYAw5NAwz5","mtq4mtm1CKzHvfjs"];_0x163c=function(){return _0x4e0487};return _0x163c()}import{BaseStore}from"./baseStore.js";import{RedisConnectionError}from"../utils/errors.js";import{SCRIPTS,SCRIPT_SHAS}from"./luaScripts.js";const require=createRequire(import.meta.url);export class RedisStore extends BaseStore{constructor(_0x48d94e={}){const _0x488b66=_0x3abe;super(),this["keyPrefix"]=_0x48d94e[_0x488b66(162)]||_0x48d94e[_0x488b66(184)]||_0x48d94e[_0x488b66(183)]||_0x48d94e["_storePrefix"]||_0x488b66(151),this[_0x488b66(153)]=Boolean(_0x48d94e[_0x488b66(153)]||_0x48d94e["passOnStoreError"]),this[_0x488b66(169)]=SCRIPTS,this["scriptShas"]=SCRIPT_SHAS,this[_0x488b66(136)]=![],this[_0x488b66(157)]=![],this[_0x488b66(204)](_0x48d94e),this["isMock"]=Boolean(_0x48d94e[_0x488b66(171)]||this[_0x488b66(161)]?.[_0x488b66(165)]instanceof Map||this[_0x488b66(161)]?.[_0x488b66(147)]?.[_0x488b66(152)]===_0x488b66(202)||this[_0x488b66(161)]?.[_0x488b66(147)]?.[_0x488b66(152)]===_0x488b66(182)),this[_0x488b66(203)]=_0x48d94e[_0x488b66(203)]!==undefined?Boolean(_0x48d94e[_0x488b66(203)]):!this[_0x488b66(171)]}[_0x5285a6(158)](){const _0x2ec556=_0x5285a6;return this[_0x2ec556(203)]?0:Date[_0x2ec556(176)]()}["_initClient"](_0x19f609){const _0x428877=_0x5285a6;let _0x15ba6f=_0x19f609[_0x428877(161)]||(_0x19f609[_0x428877(201)]&&typeof _0x19f609[_0x428877(201)][_0x428877(173)]==="function"?_0x19f609["redis"]:null)||(_0x19f609[_0x428877(201)]&&typeof _0x19f609[_0x428877(201)][_0x428877(148)]===_0x428877(140)?_0x19f609[_0x428877(201)]:null)||_0x19f609["redis"]&&_0x19f609[_0x428877(201)][_0x428877(161)]||null;!_0x15ba6f&&typeof _0x19f609[_0x428877(148)]===_0x428877(140)&&(_0x15ba6f={"sendCommand":_0x19f609[_0x428877(148)]});if(!_0x15ba6f){const _0x343464=typeof _0x19f609["redis"]===_0x428877(192)&&_0x19f609[_0x428877(201)]!==null?{..._0x19f609["redis"]}:{},_0x4c17ea=_0x19f609[_0x428877(188)]||_0x343464[_0x428877(188)];let _0x3411b1=_0x19f609[_0x428877(178)]||_0x343464["Redis"];if(!_0x3411b1)try{const _0x342c8b=require(_0x428877(167));_0x3411b1=_0x342c8b[_0x428877(175)]||_0x342c8b}catch{}if(_0x3411b1&&typeof _0x3411b1===_0x428877(140))try{_0x15ba6f=_0x4c17ea?new _0x3411b1(_0x4c17ea,_0x343464):new _0x3411b1(_0x343464),this[_0x428877(136)]=!![]}catch{_0x15ba6f=null}if(!_0x15ba6f)try{const _0x3c340a=require("redis"),_0x1eac7e=_0x3c340a[_0x428877(159)]||_0x3c340a["default"]?.[_0x428877(159)];if(typeof _0x1eac7e===_0x428877(140)){const _0x3d7c55=_0x4c17ea?{"url":_0x4c17ea,..._0x343464}:_0x343464;_0x15ba6f=_0x1eac7e(_0x3d7c55),typeof _0x15ba6f[_0x428877(185)]==="function"&&_0x15ba6f[_0x428877(185)]()[_0x428877(186)](_0x1e8836=>{const _0x41ef19=_0x428877;this[_0x41ef19(157)]=![],typeof _0x19f609["onError"]===_0x41ef19(140)&&_0x19f609["onError"](new RedisConnectionError(_0x1e8836[_0x41ef19(179)],_0x1e8836))}),this[_0x428877(136)]=!![]}}catch{}}this[_0x428877(161)]=_0x15ba6f,this[_0x428877(161)]&&typeof this[_0x428877(161)]["on"]===_0x428877(140)&&(this[_0x428877(161)]["on"]("connect",()=>{this["isConnected"]=!![]}),this[_0x428877(161)]["on"](_0x428877(187),()=>{const _0x47a232=_0x428877;this[_0x47a232(157)]=!![]}),this[_0x428877(161)]["on"](_0x428877(180),_0x3387c4=>{const _0x4f7463=_0x428877;this[_0x4f7463(157)]=![],typeof _0x19f609[_0x4f7463(170)]===_0x4f7463(140)&&_0x19f609[_0x4f7463(170)](new RedisConnectionError(_0x3387c4[_0x4f7463(179)],_0x3387c4))}),this[_0x428877(161)]["on"]("close",()=>{const _0x579078=_0x428877;this[_0x579078(157)]=![]}),this["client"]["on"](_0x428877(146),()=>{this["isConnected"]=![]})),this[_0x428877(161)]&&(this["client"][_0x428877(139)]===_0x428877(187)||this[_0x428877(161)][_0x428877(139)]===_0x428877(185)||this["client"][_0x428877(166)]||this[_0x428877(161)][_0x428877(172)])&&(this[_0x428877(157)]=!![])}["_prefixKey"](_0x4334eb){const _0x4ff8c7=_0x5285a6;return""+this[_0x4ff8c7(162)]+_0x4334eb}async[_0x5285a6(177)](_0x26817a,_0x5175cb=[],_0x12754b=[]){const _0x1e79d9=_0x5285a6,_0x39788f=this[_0x1e79d9(169)][_0x26817a],_0x1c320f=this[_0x1e79d9(196)][_0x26817a];if(!_0x39788f)throw new Error(_0x1e79d9(191)+_0x26817a+"\" not found");if(!this["client"])throw new RedisConnectionError(_0x1e79d9(145));const _0x78bf9f=_0x5175cb[_0x1e79d9(149)](_0x69ff95=>this[_0x1e79d9(193)](_0x69ff95)),_0x366a9e=_0x12754b["map"](_0x530f91=>String(_0x530f91));try{if(typeof this[_0x1e79d9(161)][_0x1e79d9(168)]===_0x1e79d9(140))try{return await this[_0x1e79d9(161)]["evalsha"](_0x1c320f,_0x78bf9f["length"],..._0x78bf9f,..._0x366a9e)}catch(_0xfe0bfd){if(_0xfe0bfd[_0x1e79d9(179)]&&_0xfe0bfd[_0x1e79d9(179)][_0x1e79d9(138)](_0x1e79d9(160)))return await this[_0x1e79d9(161)][_0x1e79d9(173)](_0x39788f,_0x78bf9f[_0x1e79d9(135)],..._0x78bf9f,..._0x366a9e);throw _0xfe0bfd}if(typeof this[_0x1e79d9(161)]["eval"]===_0x1e79d9(140)){if(typeof this[_0x1e79d9(161)][_0x1e79d9(173)][_0x1e79d9(135)]==="number"&&this[_0x1e79d9(161)][_0x1e79d9(173)][_0x1e79d9(135)]<=1)return await this["client"]["eval"](_0x39788f,{"keys":_0x78bf9f,"arguments":_0x366a9e});return await this[_0x1e79d9(161)][_0x1e79d9(173)](_0x39788f,_0x78bf9f[_0x1e79d9(135)],..._0x78bf9f,..._0x366a9e)}if(typeof this[_0x1e79d9(161)][_0x1e79d9(148)]===_0x1e79d9(140))try{return await this[_0x1e79d9(161)]["sendCommand"]([_0x1e79d9(198),_0x1c320f,String(_0x78bf9f[_0x1e79d9(135)]),..._0x78bf9f,..._0x366a9e])}catch(_0x302cc1){if(_0x302cc1[_0x1e79d9(179)]&&_0x302cc1["message"][_0x1e79d9(138)](_0x1e79d9(160)))return await this[_0x1e79d9(161)][_0x1e79d9(148)]([_0x1e79d9(137),_0x39788f,String(_0x78bf9f[_0x1e79d9(135)]),..._0x78bf9f,..._0x366a9e]);throw _0x302cc1}throw new Error(_0x1e79d9(174))}catch(_0x142d3f){throw new RedisConnectionError("Redis script execution error: "+_0x142d3f[_0x1e79d9(179)],_0x142d3f)}}async[_0x5285a6(200)](_0x57215b){const _0x10c30a=_0x5285a6;try{const _0x26159f=this["_prefixKey"](_0x57215b);let _0x2752fc;if(typeof this[_0x10c30a(161)]?.[_0x10c30a(200)]==="function")_0x2752fc=await this[_0x10c30a(161)][_0x10c30a(200)](_0x26159f);else typeof this["client"]?.[_0x10c30a(148)]===_0x10c30a(140)&&(_0x2752fc=await this[_0x10c30a(161)]["sendCommand"]([_0x10c30a(195),_0x26159f]));if(!_0x2752fc)return null;try{return JSON[_0x10c30a(208)](_0x2752fc)}catch{return _0x2752fc}}catch(_0x1e7a2e){throw new RedisConnectionError(_0x10c30a(155)+_0x1e7a2e["message"],_0x1e7a2e)}}async["set"](_0xa65221,_0x239e75,_0x4e7bce){const _0x54def5=_0x5285a6;try{const _0x271e67=this[_0x54def5(193)](_0xa65221),_0x7346dc=typeof _0x239e75===_0x54def5(192)?JSON[_0x54def5(205)](_0x239e75):String(_0x239e75);if(typeof this[_0x54def5(161)]?.[_0x54def5(209)]==="function")_0x4e7bce&&_0x4e7bce>0?await this[_0x54def5(161)][_0x54def5(209)](_0x271e67,_0x7346dc,"PX",_0x4e7bce):await this[_0x54def5(161)][_0x54def5(209)](_0x271e67,_0x7346dc);else typeof this[_0x54def5(161)]?.[_0x54def5(148)]===_0x54def5(140)&&(_0x4e7bce&&_0x4e7bce>0?await this[_0x54def5(161)][_0x54def5(148)]([_0x54def5(199),_0x271e67,_0x7346dc,"PX",String(_0x4e7bce)]):await this[_0x54def5(161)][_0x54def5(148)]([_0x54def5(199),_0x271e67,_0x7346dc]));return!![]}catch(_0x460164){throw new RedisConnectionError("Redis set error: "+_0x460164[_0x54def5(179)],_0x460164)}}async["delete"](_0x29dbd8){const _0x2bb236=_0x5285a6;try{const _0x5a78c6=this[_0x2bb236(193)](_0x29dbd8);let _0x2a070d=0;if(typeof this[_0x2bb236(161)]?.["del"]===_0x2bb236(140))_0x2a070d=await this["client"][_0x2bb236(150)](_0x5a78c6);else typeof this["client"]?.[_0x2bb236(148)]===_0x2bb236(140)&&(_0x2a070d=await this[_0x2bb236(161)][_0x2bb236(148)](["DEL",_0x5a78c6]));return _0x2a070d>0}catch(_0x357951){throw new RedisConnectionError(_0x2bb236(144)+_0x357951["message"],_0x357951)}}async[_0x5285a6(194)](){const _0x2ec9a1=_0x5285a6;try{const _0xe5e3e5=this[_0x2ec9a1(162)]+"*";let _0x11a827=[];if(typeof this["client"]?.[_0x2ec9a1(154)]===_0x2ec9a1(140))_0x11a827=await this[_0x2ec9a1(161)][_0x2ec9a1(154)](_0xe5e3e5);else typeof this[_0x2ec9a1(161)]?.["sendCommand"]==="function"&&(_0x11a827=await this["client"][_0x2ec9a1(148)]([_0x2ec9a1(163),_0xe5e3e5]));if(_0x11a827&&_0x11a827[_0x2ec9a1(135)]>0){if(typeof this["client"]?.[_0x2ec9a1(150)]==="function")await this[_0x2ec9a1(161)][_0x2ec9a1(150)](..._0x11a827);else typeof this[_0x2ec9a1(161)]?.[_0x2ec9a1(148)]===_0x2ec9a1(140)&&(await this["client"]["sendCommand"](["DEL",..._0x11a827]))}}catch(_0x5bbead){throw new RedisConnectionError(_0x2ec9a1(207)+_0x5bbead[_0x2ec9a1(179)],_0x5bbead)}}async["close"](){const _0x8c9a=_0x5285a6;if(this[_0x8c9a(136)]&&this[_0x8c9a(161)]){if(typeof this[_0x8c9a(161)]["quit"]===_0x8c9a(140))await this[_0x8c9a(161)][_0x8c9a(189)]();else typeof this[_0x8c9a(161)][_0x8c9a(142)]===_0x8c9a(140)&&this[_0x8c9a(161)]["disconnect"]()}}}export default RedisStore;
1
+ import{createRequire}from'module';import{BaseStore}from'./baseStore.js';import{RedisConnectionError}from'../utils/errors.js';import{RedisClientAdapter}from'../utils/redisClient.js';import{SCRIPTS,SCRIPT_SHAS}from'./luaScripts.js';const require=createRequire(import.meta.url);export class RedisStore extends BaseStore{constructor(options={}){super();this.keyPrefix=options.keyPrefix||options.prefix||options.storePrefix||options._storePrefix||'rl:';this.failOpen=Boolean(options.failOpen||options.passOnStoreError);this.scripts=SCRIPTS;this.scriptShas=SCRIPT_SHAS;this.isInternalClient=false;this.isConnected=false;this._initClient(options);this.isMock=Boolean(options.isMock||this.client?.data instanceof Map||this.client?.constructor?.name==='RedisMock'||this.client?.constructor?.name==='_RedisMock');this.useRedisTime=options.useRedisTime!==undefined?Boolean(options.useRedisTime):!this.isMock;}getNow(){return this.useRedisTime?0:Date.now();}_initClient(options){let client=options.client||(options.redis&&typeof options.redis.eval==='function'?options.redis:null)||(options.redis&&typeof options.redis.sendCommand==='function'?options.redis:null)||options.redis&&options.redis.client||null;if(!client&&typeof options.sendCommand==='function'){client={sendCommand:options.sendCommand};}if(!client){const redisOptions=typeof options.redis==='object'&&options.redis!==null?{...options.redis}:{};const url=options.url||redisOptions.url;let Redis=options.Redis||redisOptions.Redis;if(!Redis){try{const ioredis=require('ioredis');Redis=ioredis.default||ioredis;}catch{}}if(Redis&&typeof Redis==='function'){try{client=url?new Redis(url,redisOptions):new Redis(redisOptions);this.isInternalClient=true;}catch{client=null;}}if(!client){try{const redisPkg=require('redis');const createClient=redisPkg.createClient||redisPkg.default?.createClient;if(typeof createClient==='function'){const clientOpts=url?{url,...redisOptions}:redisOptions;client=createClient(clientOpts);if(typeof client.connect==='function'){client.connect().catch(err=>{this.isConnected=false;if(typeof options.onError==='function'){options.onError(new RedisConnectionError(err.message,err));}});}this.isInternalClient=true;}}catch{}}}this.client=client;this.adapter=new RedisClientAdapter(client);if(this.client&&typeof this.client.on==='function'){this.client.on('connect',()=>{this.isConnected=true;});this.client.on('ready',()=>{this.isConnected=true;});this.client.on('error',err=>{this.isConnected=false;if(typeof options.onError==='function'){options.onError(new RedisConnectionError(err.message,err));}});this.client.on('close',()=>{this.isConnected=false;});this.client.on('end',()=>{this.isConnected=false;});}if(this.client&&(this.client.status==='ready'||this.client.status==='connect'||this.client.isReady||this.client.isOpen)){this.isConnected=true;}}_prefixKey(key){return`${this.keyPrefix}${key}`;}async runScript(scriptName,keys=[],args=[]){const script=this.scripts[scriptName];if(!script){throw new Error(`Lua script "${scriptName}" not found`);}if(!this.client){throw new RedisConnectionError('Redis client is not configured or available. Please install "ioredis" or "redis", or provide an active client instance via the "client" option.');}const prefixedKeys=keys.map(k=>this._prefixKey(k));const stringArgs=args.map(a=>String(a));try{return await this.adapter.evalScript(script,prefixedKeys,stringArgs);}catch(err){throw new RedisConnectionError(`Redis script execution error: ${err.message}`,err);}}async get(key){try{const fullKey=this._prefixKey(key);let res;if(typeof this.client?.get==='function'){res=await this.client.get(fullKey);}else if(typeof this.client?.sendCommand==='function'){res=await this.adapter.sendCommand(['GET',fullKey]);}if(!res)return null;try{return JSON.parse(res);}catch{return res;}}catch(err){throw new RedisConnectionError(`Redis get error: ${err.message}`,err);}}async set(key,value,ttlMs){try{const fullKey=this._prefixKey(key);const stringValue=typeof value==='object'?JSON.stringify(value):String(value);await this.adapter.setWithTtl(fullKey,stringValue,ttlMs);return true;}catch(err){throw new RedisConnectionError(`Redis set error: ${err.message}`,err);}}async delete(key){try{const fullKey=this._prefixKey(key);return this.adapter.del(fullKey);}catch(err){throw new RedisConnectionError(`Redis del error: ${err.message}`,err);}}async clear(){try{const pattern=`${this.keyPrefix}*`;const keys=await this.adapter.scanKeys(pattern);if(keys&&keys.length>0){await this.adapter.delMany(keys);}}catch(err){throw new RedisConnectionError(`Redis clear error: ${err.message}`,err);}}async close(){if(this.isInternalClient&&this.client){if(typeof this.client.quit==='function'){await this.client.quit();}else if(typeof this.client.disconnect==='function'){this.client.disconnect();}}}}export default RedisStore;