@upstash/ratelimit 2.0.2 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -134,38 +134,181 @@ function ms(d) {
134
134
  }
135
135
 
136
136
  // src/hash.ts
137
- var setHash = async (ctx, script, kind) => {
138
- const regionContexts = "redis" in ctx ? [ctx] : ctx.regionContexts;
139
- const hashSample = regionContexts[0].scriptHashes[kind];
140
- if (!hashSample) {
141
- await Promise.all(regionContexts.map(async (context) => {
142
- context.scriptHashes[kind] = await context.redis.scriptLoad(script);
143
- }));
144
- }
145
- ;
146
- };
147
- var safeEval = async (ctx, script, kind, keys, args) => {
148
- if (!ctx.cacheScripts) {
149
- return await ctx.redis.eval(script, keys, args);
150
- }
151
- ;
152
- await setHash(ctx, script, kind);
137
+ var safeEval = async (ctx, script, keys, args) => {
153
138
  try {
154
- return await ctx.redis.evalsha(ctx.scriptHashes[kind], keys, args);
139
+ return await ctx.redis.evalsha(script.hash, keys, args);
155
140
  } catch (error) {
156
141
  if (`${error}`.includes("NOSCRIPT")) {
157
- console.log("Script with the expected hash was not found in redis db. It is probably flushed. Will load another scipt before continuing.");
158
- ctx.scriptHashes[kind] = void 0;
159
- await setHash(ctx, script, kind);
160
- console.log(" New script successfully loaded.");
161
- return await ctx.redis.evalsha(ctx.scriptHashes[kind], keys, args);
142
+ const hash = await ctx.redis.scriptLoad(script.script);
143
+ if (hash !== script.hash) {
144
+ console.warn(
145
+ "Upstash Ratelimit: Expected hash and the hash received from Redis are different. Ratelimit will work as usual but performance will be reduced."
146
+ );
147
+ }
148
+ return await ctx.redis.evalsha(hash, keys, args);
162
149
  }
163
150
  throw error;
164
151
  }
165
152
  };
166
153
 
167
- // src/lua-scripts/multi.ts
154
+ // src/lua-scripts/single.ts
168
155
  var fixedWindowLimitScript = `
156
+ local key = KEYS[1]
157
+ local window = ARGV[1]
158
+ local incrementBy = ARGV[2] -- increment rate per request at a given value, default is 1
159
+
160
+ local r = redis.call("INCRBY", key, incrementBy)
161
+ if r == tonumber(incrementBy) then
162
+ -- The first time this key is set, the value will be equal to incrementBy.
163
+ -- So we only need the expire command once
164
+ redis.call("PEXPIRE", key, window)
165
+ end
166
+
167
+ return r
168
+ `;
169
+ var fixedWindowRemainingTokensScript = `
170
+ local key = KEYS[1]
171
+ local tokens = 0
172
+
173
+ local value = redis.call('GET', key)
174
+ if value then
175
+ tokens = value
176
+ end
177
+ return tokens
178
+ `;
179
+ var slidingWindowLimitScript = `
180
+ local currentKey = KEYS[1] -- identifier including prefixes
181
+ local previousKey = KEYS[2] -- key of the previous bucket
182
+ local tokens = tonumber(ARGV[1]) -- tokens per window
183
+ local now = ARGV[2] -- current timestamp in milliseconds
184
+ local window = ARGV[3] -- interval in milliseconds
185
+ local incrementBy = ARGV[4] -- increment rate per request at a given value, default is 1
186
+
187
+ local requestsInCurrentWindow = redis.call("GET", currentKey)
188
+ if requestsInCurrentWindow == false then
189
+ requestsInCurrentWindow = 0
190
+ end
191
+
192
+ local requestsInPreviousWindow = redis.call("GET", previousKey)
193
+ if requestsInPreviousWindow == false then
194
+ requestsInPreviousWindow = 0
195
+ end
196
+ local percentageInCurrent = ( now % window ) / window
197
+ -- weighted requests to consider from the previous window
198
+ requestsInPreviousWindow = math.floor(( 1 - percentageInCurrent ) * requestsInPreviousWindow)
199
+ if requestsInPreviousWindow + requestsInCurrentWindow >= tokens then
200
+ return -1
201
+ end
202
+
203
+ local newValue = redis.call("INCRBY", currentKey, incrementBy)
204
+ if newValue == tonumber(incrementBy) then
205
+ -- The first time this key is set, the value will be equal to incrementBy.
206
+ -- So we only need the expire command once
207
+ redis.call("PEXPIRE", currentKey, window * 2 + 1000) -- Enough time to overlap with a new window + 1 second
208
+ end
209
+ return tokens - ( newValue + requestsInPreviousWindow )
210
+ `;
211
+ var slidingWindowRemainingTokensScript = `
212
+ local currentKey = KEYS[1] -- identifier including prefixes
213
+ local previousKey = KEYS[2] -- key of the previous bucket
214
+ local now = ARGV[1] -- current timestamp in milliseconds
215
+ local window = ARGV[2] -- interval in milliseconds
216
+
217
+ local requestsInCurrentWindow = redis.call("GET", currentKey)
218
+ if requestsInCurrentWindow == false then
219
+ requestsInCurrentWindow = 0
220
+ end
221
+
222
+ local requestsInPreviousWindow = redis.call("GET", previousKey)
223
+ if requestsInPreviousWindow == false then
224
+ requestsInPreviousWindow = 0
225
+ end
226
+
227
+ local percentageInCurrent = ( now % window ) / window
228
+ -- weighted requests to consider from the previous window
229
+ requestsInPreviousWindow = math.floor(( 1 - percentageInCurrent ) * requestsInPreviousWindow)
230
+
231
+ return requestsInPreviousWindow + requestsInCurrentWindow
232
+ `;
233
+ var tokenBucketLimitScript = `
234
+ local key = KEYS[1] -- identifier including prefixes
235
+ local maxTokens = tonumber(ARGV[1]) -- maximum number of tokens
236
+ local interval = tonumber(ARGV[2]) -- size of the window in milliseconds
237
+ local refillRate = tonumber(ARGV[3]) -- how many tokens are refilled after each interval
238
+ local now = tonumber(ARGV[4]) -- current timestamp in milliseconds
239
+ local incrementBy = tonumber(ARGV[5]) -- how many tokens to consume, default is 1
240
+
241
+ local bucket = redis.call("HMGET", key, "refilledAt", "tokens")
242
+
243
+ local refilledAt
244
+ local tokens
245
+
246
+ if bucket[1] == false then
247
+ refilledAt = now
248
+ tokens = maxTokens
249
+ else
250
+ refilledAt = tonumber(bucket[1])
251
+ tokens = tonumber(bucket[2])
252
+ end
253
+
254
+ if now >= refilledAt + interval then
255
+ local numRefills = math.floor((now - refilledAt) / interval)
256
+ tokens = math.min(maxTokens, tokens + numRefills * refillRate)
257
+
258
+ refilledAt = refilledAt + numRefills * interval
259
+ end
260
+
261
+ if tokens == 0 then
262
+ return {-1, refilledAt + interval}
263
+ end
264
+
265
+ local remaining = tokens - incrementBy
266
+ local expireAt = math.ceil(((maxTokens - remaining) / refillRate)) * interval
267
+
268
+ redis.call("HSET", key, "refilledAt", refilledAt, "tokens", remaining)
269
+ redis.call("PEXPIRE", key, expireAt)
270
+ return {remaining, refilledAt + interval}
271
+ `;
272
+ var tokenBucketIdentifierNotFound = -1;
273
+ var tokenBucketRemainingTokensScript = `
274
+ local key = KEYS[1]
275
+ local maxTokens = tonumber(ARGV[1])
276
+
277
+ local bucket = redis.call("HMGET", key, "refilledAt", "tokens")
278
+
279
+ if bucket[1] == false then
280
+ return {maxTokens, ${tokenBucketIdentifierNotFound}}
281
+ end
282
+
283
+ return {tonumber(bucket[2]), tonumber(bucket[1])}
284
+ `;
285
+ var cachedFixedWindowLimitScript = `
286
+ local key = KEYS[1]
287
+ local window = ARGV[1]
288
+ local incrementBy = ARGV[2] -- increment rate per request at a given value, default is 1
289
+
290
+ local r = redis.call("INCRBY", key, incrementBy)
291
+ if r == incrementBy then
292
+ -- The first time this key is set, the value will be equal to incrementBy.
293
+ -- So we only need the expire command once
294
+ redis.call("PEXPIRE", key, window)
295
+ end
296
+
297
+ return r
298
+ `;
299
+ var cachedFixedWindowRemainingTokenScript = `
300
+ local key = KEYS[1]
301
+ local tokens = 0
302
+
303
+ local value = redis.call('GET', key)
304
+ if value then
305
+ tokens = value
306
+ end
307
+ return tokens
308
+ `;
309
+
310
+ // src/lua-scripts/multi.ts
311
+ var fixedWindowLimitScript2 = `
169
312
  local key = KEYS[1]
170
313
  local id = ARGV[1]
171
314
  local window = ARGV[2]
@@ -181,7 +324,7 @@ var fixedWindowLimitScript = `
181
324
 
182
325
  return fields
183
326
  `;
184
- var fixedWindowRemainingTokensScript = `
327
+ var fixedWindowRemainingTokensScript2 = `
185
328
  local key = KEYS[1]
186
329
  local tokens = 0
187
330
 
@@ -189,7 +332,7 @@ var fixedWindowRemainingTokensScript = `
189
332
 
190
333
  return fields
191
334
  `;
192
- var slidingWindowLimitScript = `
335
+ var slidingWindowLimitScript2 = `
193
336
  local currentKey = KEYS[1] -- identifier including prefixes
194
337
  local previousKey = KEYS[2] -- key of the previous bucket
195
338
  local tokens = tonumber(ARGV[1]) -- tokens per window
@@ -224,7 +367,7 @@ var slidingWindowLimitScript = `
224
367
  end
225
368
  return {currentFields, previousFields, true}
226
369
  `;
227
- var slidingWindowRemainingTokensScript = `
370
+ var slidingWindowRemainingTokensScript2 = `
228
371
  local currentKey = KEYS[1] -- identifier including prefixes
229
372
  local previousKey = KEYS[2] -- key of the previous bucket
230
373
  local now = ARGV[1] -- current timestamp in milliseconds
@@ -273,6 +416,78 @@ var resetScript = `
273
416
  until cursor == "0"
274
417
  `;
275
418
 
419
+ // src/lua-scripts/hash.ts
420
+ var SCRIPTS = {
421
+ singleRegion: {
422
+ fixedWindow: {
423
+ limit: {
424
+ script: fixedWindowLimitScript,
425
+ hash: "b13943e359636db027ad280f1def143f02158c13"
426
+ },
427
+ getRemaining: {
428
+ script: fixedWindowRemainingTokensScript,
429
+ hash: "8c4c341934502aee132643ffbe58ead3450e5208"
430
+ }
431
+ },
432
+ slidingWindow: {
433
+ limit: {
434
+ script: slidingWindowLimitScript,
435
+ hash: "e1391e429b699c780eb0480350cd5b7280fd9213"
436
+ },
437
+ getRemaining: {
438
+ script: slidingWindowRemainingTokensScript,
439
+ hash: "65a73ac5a05bf9712903bc304b77268980c1c417"
440
+ }
441
+ },
442
+ tokenBucket: {
443
+ limit: {
444
+ script: tokenBucketLimitScript,
445
+ hash: "5bece90aeef8189a8cfd28995b479529e270b3c6"
446
+ },
447
+ getRemaining: {
448
+ script: tokenBucketRemainingTokensScript,
449
+ hash: "a15be2bb1db2a15f7c82db06146f9d08983900d0"
450
+ }
451
+ },
452
+ cachedFixedWindow: {
453
+ limit: {
454
+ script: cachedFixedWindowLimitScript,
455
+ hash: "c26b12703dd137939b9a69a3a9b18e906a2d940f"
456
+ },
457
+ getRemaining: {
458
+ script: cachedFixedWindowRemainingTokenScript,
459
+ hash: "8e8f222ccae68b595ee6e3f3bf2199629a62b91a"
460
+ }
461
+ }
462
+ },
463
+ multiRegion: {
464
+ fixedWindow: {
465
+ limit: {
466
+ script: fixedWindowLimitScript2,
467
+ hash: "a8c14f3835aa87bd70e5e2116081b81664abcf5c"
468
+ },
469
+ getRemaining: {
470
+ script: fixedWindowRemainingTokensScript2,
471
+ hash: "8ab8322d0ed5fe5ac8eb08f0c2e4557f1b4816fd"
472
+ }
473
+ },
474
+ slidingWindow: {
475
+ limit: {
476
+ script: slidingWindowLimitScript2,
477
+ hash: "cb4fdc2575056df7c6d422764df0de3a08d6753b"
478
+ },
479
+ getRemaining: {
480
+ script: slidingWindowRemainingTokensScript2,
481
+ hash: "558c9306b7ec54abb50747fe0b17e5d44bd24868"
482
+ }
483
+ }
484
+ }
485
+ };
486
+ var RESET_SCRIPT = {
487
+ script: resetScript,
488
+ hash: "54bd274ddc59fb3be0f42deee2f64322a10e2b50"
489
+ };
490
+
276
491
  // src/types.ts
277
492
  var DenyListExtension = "denyList";
278
493
  var IpDenyListKey = "ipDenyList";
@@ -712,9 +927,7 @@ var MultiRegionRatelimit = class extends Ratelimit {
712
927
  analytics: config.analytics,
713
928
  ctx: {
714
929
  regionContexts: config.redis.map((redis) => ({
715
- redis,
716
- scriptHashes: {},
717
- cacheScripts: config.cacheScripts ?? true
930
+ redis
718
931
  })),
719
932
  cache: config.ephemeralCache ? new Cache(config.ephemeralCache) : void 0
720
933
  }
@@ -763,8 +976,7 @@ var MultiRegionRatelimit = class extends Ratelimit {
763
976
  redis: regionContext.redis,
764
977
  request: safeEval(
765
978
  regionContext,
766
- fixedWindowLimitScript,
767
- "limitHash",
979
+ SCRIPTS.multiRegion.fixedWindow.limit,
768
980
  [key],
769
981
  [requestId, windowDuration, incrementBy]
770
982
  )
@@ -839,8 +1051,7 @@ var MultiRegionRatelimit = class extends Ratelimit {
839
1051
  redis: regionContext.redis,
840
1052
  request: safeEval(
841
1053
  regionContext,
842
- fixedWindowRemainingTokensScript,
843
- "getRemainingHash",
1054
+ SCRIPTS.multiRegion.fixedWindow.getRemaining,
844
1055
  [key],
845
1056
  [null]
846
1057
  )
@@ -866,8 +1077,7 @@ var MultiRegionRatelimit = class extends Ratelimit {
866
1077
  await Promise.all(ctx.regionContexts.map((regionContext) => {
867
1078
  safeEval(
868
1079
  regionContext,
869
- resetScript,
870
- "resetHash",
1080
+ RESET_SCRIPT,
871
1081
  [pattern],
872
1082
  [null]
873
1083
  );
@@ -920,8 +1130,7 @@ var MultiRegionRatelimit = class extends Ratelimit {
920
1130
  redis: regionContext.redis,
921
1131
  request: safeEval(
922
1132
  regionContext,
923
- slidingWindowLimitScript,
924
- "limitHash",
1133
+ SCRIPTS.multiRegion.slidingWindow.limit,
925
1134
  [currentKey, previousKey],
926
1135
  [tokens, now, windowDuration, requestId, incrementBy]
927
1136
  // lua seems to return `1` for true and `null` for false
@@ -1010,8 +1219,7 @@ var MultiRegionRatelimit = class extends Ratelimit {
1010
1219
  redis: regionContext.redis,
1011
1220
  request: safeEval(
1012
1221
  regionContext,
1013
- slidingWindowRemainingTokensScript,
1014
- "getRemainingHash",
1222
+ SCRIPTS.multiRegion.slidingWindow.getRemaining,
1015
1223
  [currentKey, previousKey],
1016
1224
  [now, windowSize]
1017
1225
  // lua seems to return `1` for true and `null` for false
@@ -1031,8 +1239,7 @@ var MultiRegionRatelimit = class extends Ratelimit {
1031
1239
  await Promise.all(ctx.regionContexts.map((regionContext) => {
1032
1240
  safeEval(
1033
1241
  regionContext,
1034
- resetScript,
1035
- "resetHash",
1242
+ RESET_SCRIPT,
1036
1243
  [pattern],
1037
1244
  [null]
1038
1245
  );
@@ -1042,162 +1249,6 @@ var MultiRegionRatelimit = class extends Ratelimit {
1042
1249
  }
1043
1250
  };
1044
1251
 
1045
- // src/lua-scripts/single.ts
1046
- var fixedWindowLimitScript2 = `
1047
- local key = KEYS[1]
1048
- local window = ARGV[1]
1049
- local incrementBy = ARGV[2] -- increment rate per request at a given value, default is 1
1050
-
1051
- local r = redis.call("INCRBY", key, incrementBy)
1052
- if r == tonumber(incrementBy) then
1053
- -- The first time this key is set, the value will be equal to incrementBy.
1054
- -- So we only need the expire command once
1055
- redis.call("PEXPIRE", key, window)
1056
- end
1057
-
1058
- return r
1059
- `;
1060
- var fixedWindowRemainingTokensScript2 = `
1061
- local key = KEYS[1]
1062
- local tokens = 0
1063
-
1064
- local value = redis.call('GET', key)
1065
- if value then
1066
- tokens = value
1067
- end
1068
- return tokens
1069
- `;
1070
- var slidingWindowLimitScript2 = `
1071
- local currentKey = KEYS[1] -- identifier including prefixes
1072
- local previousKey = KEYS[2] -- key of the previous bucket
1073
- local tokens = tonumber(ARGV[1]) -- tokens per window
1074
- local now = ARGV[2] -- current timestamp in milliseconds
1075
- local window = ARGV[3] -- interval in milliseconds
1076
- local incrementBy = ARGV[4] -- increment rate per request at a given value, default is 1
1077
-
1078
- local requestsInCurrentWindow = redis.call("GET", currentKey)
1079
- if requestsInCurrentWindow == false then
1080
- requestsInCurrentWindow = 0
1081
- end
1082
-
1083
- local requestsInPreviousWindow = redis.call("GET", previousKey)
1084
- if requestsInPreviousWindow == false then
1085
- requestsInPreviousWindow = 0
1086
- end
1087
- local percentageInCurrent = ( now % window ) / window
1088
- -- weighted requests to consider from the previous window
1089
- requestsInPreviousWindow = math.floor(( 1 - percentageInCurrent ) * requestsInPreviousWindow)
1090
- if requestsInPreviousWindow + requestsInCurrentWindow >= tokens then
1091
- return -1
1092
- end
1093
-
1094
- local newValue = redis.call("INCRBY", currentKey, incrementBy)
1095
- if newValue == tonumber(incrementBy) then
1096
- -- The first time this key is set, the value will be equal to incrementBy.
1097
- -- So we only need the expire command once
1098
- redis.call("PEXPIRE", currentKey, window * 2 + 1000) -- Enough time to overlap with a new window + 1 second
1099
- end
1100
- return tokens - ( newValue + requestsInPreviousWindow )
1101
- `;
1102
- var slidingWindowRemainingTokensScript2 = `
1103
- local currentKey = KEYS[1] -- identifier including prefixes
1104
- local previousKey = KEYS[2] -- key of the previous bucket
1105
- local now = ARGV[1] -- current timestamp in milliseconds
1106
- local window = ARGV[2] -- interval in milliseconds
1107
-
1108
- local requestsInCurrentWindow = redis.call("GET", currentKey)
1109
- if requestsInCurrentWindow == false then
1110
- requestsInCurrentWindow = 0
1111
- end
1112
-
1113
- local requestsInPreviousWindow = redis.call("GET", previousKey)
1114
- if requestsInPreviousWindow == false then
1115
- requestsInPreviousWindow = 0
1116
- end
1117
-
1118
- local percentageInCurrent = ( now % window ) / window
1119
- -- weighted requests to consider from the previous window
1120
- requestsInPreviousWindow = math.floor(( 1 - percentageInCurrent ) * requestsInPreviousWindow)
1121
-
1122
- return requestsInPreviousWindow + requestsInCurrentWindow
1123
- `;
1124
- var tokenBucketLimitScript = `
1125
- local key = KEYS[1] -- identifier including prefixes
1126
- local maxTokens = tonumber(ARGV[1]) -- maximum number of tokens
1127
- local interval = tonumber(ARGV[2]) -- size of the window in milliseconds
1128
- local refillRate = tonumber(ARGV[3]) -- how many tokens are refilled after each interval
1129
- local now = tonumber(ARGV[4]) -- current timestamp in milliseconds
1130
- local incrementBy = tonumber(ARGV[5]) -- how many tokens to consume, default is 1
1131
-
1132
- local bucket = redis.call("HMGET", key, "refilledAt", "tokens")
1133
-
1134
- local refilledAt
1135
- local tokens
1136
-
1137
- if bucket[1] == false then
1138
- refilledAt = now
1139
- tokens = maxTokens
1140
- else
1141
- refilledAt = tonumber(bucket[1])
1142
- tokens = tonumber(bucket[2])
1143
- end
1144
-
1145
- if now >= refilledAt + interval then
1146
- local numRefills = math.floor((now - refilledAt) / interval)
1147
- tokens = math.min(maxTokens, tokens + numRefills * refillRate)
1148
-
1149
- refilledAt = refilledAt + numRefills * interval
1150
- end
1151
-
1152
- if tokens == 0 then
1153
- return {-1, refilledAt + interval}
1154
- end
1155
-
1156
- local remaining = tokens - incrementBy
1157
- local expireAt = math.ceil(((maxTokens - remaining) / refillRate)) * interval
1158
-
1159
- redis.call("HSET", key, "refilledAt", refilledAt, "tokens", remaining)
1160
- redis.call("PEXPIRE", key, expireAt)
1161
- return {remaining, refilledAt + interval}
1162
- `;
1163
- var tokenBucketIdentifierNotFound = -1;
1164
- var tokenBucketRemainingTokensScript = `
1165
- local key = KEYS[1]
1166
- local maxTokens = tonumber(ARGV[1])
1167
-
1168
- local bucket = redis.call("HMGET", key, "refilledAt", "tokens")
1169
-
1170
- if bucket[1] == false then
1171
- return {maxTokens, ${tokenBucketIdentifierNotFound}}
1172
- end
1173
-
1174
- return {tonumber(bucket[2]), tonumber(bucket[1])}
1175
- `;
1176
- var cachedFixedWindowLimitScript = `
1177
- local key = KEYS[1]
1178
- local window = ARGV[1]
1179
- local incrementBy = ARGV[2] -- increment rate per request at a given value, default is 1
1180
-
1181
- local r = redis.call("INCRBY", key, incrementBy)
1182
- if r == incrementBy then
1183
- -- The first time this key is set, the value will be equal to incrementBy.
1184
- -- So we only need the expire command once
1185
- redis.call("PEXPIRE", key, window)
1186
- end
1187
-
1188
- return r
1189
- `;
1190
- var cachedFixedWindowRemainingTokenScript = `
1191
- local key = KEYS[1]
1192
- local tokens = 0
1193
-
1194
- local value = redis.call('GET', key)
1195
- if value then
1196
- tokens = value
1197
- end
1198
- return tokens
1199
- `;
1200
-
1201
1252
  // src/single.ts
1202
1253
  var RegionRatelimit = class extends Ratelimit {
1203
1254
  /**
@@ -1210,9 +1261,7 @@ var RegionRatelimit = class extends Ratelimit {
1210
1261
  timeout: config.timeout,
1211
1262
  analytics: config.analytics,
1212
1263
  ctx: {
1213
- redis: config.redis,
1214
- scriptHashes: {},
1215
- cacheScripts: config.cacheScripts ?? true
1264
+ redis: config.redis
1216
1265
  },
1217
1266
  ephemeralCache: config.ephemeralCache,
1218
1267
  enableProtection: config.enableProtection,
@@ -1259,8 +1308,7 @@ var RegionRatelimit = class extends Ratelimit {
1259
1308
  const incrementBy = rate ? Math.max(1, rate) : 1;
1260
1309
  const usedTokensAfterUpdate = await safeEval(
1261
1310
  ctx,
1262
- fixedWindowLimitScript2,
1263
- "limitHash",
1311
+ SCRIPTS.singleRegion.fixedWindow.limit,
1264
1312
  [key],
1265
1313
  [windowDuration, incrementBy]
1266
1314
  );
@@ -1283,8 +1331,7 @@ var RegionRatelimit = class extends Ratelimit {
1283
1331
  const key = [identifier, bucket].join(":");
1284
1332
  const usedTokens = await safeEval(
1285
1333
  ctx,
1286
- fixedWindowRemainingTokensScript2,
1287
- "getRemainingHash",
1334
+ SCRIPTS.singleRegion.fixedWindow.getRemaining,
1288
1335
  [key],
1289
1336
  [null]
1290
1337
  );
@@ -1300,8 +1347,7 @@ var RegionRatelimit = class extends Ratelimit {
1300
1347
  }
1301
1348
  await safeEval(
1302
1349
  ctx,
1303
- resetScript,
1304
- "resetHash",
1350
+ RESET_SCRIPT,
1305
1351
  [pattern],
1306
1352
  [null]
1307
1353
  );
@@ -1349,8 +1395,7 @@ var RegionRatelimit = class extends Ratelimit {
1349
1395
  const incrementBy = rate ? Math.max(1, rate) : 1;
1350
1396
  const remainingTokens = await safeEval(
1351
1397
  ctx,
1352
- slidingWindowLimitScript2,
1353
- "limitHash",
1398
+ SCRIPTS.singleRegion.slidingWindow.limit,
1354
1399
  [currentKey, previousKey],
1355
1400
  [tokens, now, windowSize, incrementBy]
1356
1401
  );
@@ -1375,8 +1420,7 @@ var RegionRatelimit = class extends Ratelimit {
1375
1420
  const previousKey = [identifier, previousWindow].join(":");
1376
1421
  const usedTokens = await safeEval(
1377
1422
  ctx,
1378
- slidingWindowRemainingTokensScript2,
1379
- "getRemainingHash",
1423
+ SCRIPTS.singleRegion.slidingWindow.getRemaining,
1380
1424
  [currentKey, previousKey],
1381
1425
  [now, windowSize]
1382
1426
  );
@@ -1392,8 +1436,7 @@ var RegionRatelimit = class extends Ratelimit {
1392
1436
  }
1393
1437
  await safeEval(
1394
1438
  ctx,
1395
- resetScript,
1396
- "resetHash",
1439
+ RESET_SCRIPT,
1397
1440
  [pattern],
1398
1441
  [null]
1399
1442
  );
@@ -1434,8 +1477,7 @@ var RegionRatelimit = class extends Ratelimit {
1434
1477
  const incrementBy = rate ? Math.max(1, rate) : 1;
1435
1478
  const [remaining, reset] = await safeEval(
1436
1479
  ctx,
1437
- tokenBucketLimitScript,
1438
- "limitHash",
1480
+ SCRIPTS.singleRegion.tokenBucket.limit,
1439
1481
  [identifier],
1440
1482
  [maxTokens, intervalDuration, refillRate, now, incrementBy]
1441
1483
  );
@@ -1454,8 +1496,7 @@ var RegionRatelimit = class extends Ratelimit {
1454
1496
  async getRemaining(ctx, identifier) {
1455
1497
  const [remainingTokens, refilledAt] = await safeEval(
1456
1498
  ctx,
1457
- tokenBucketRemainingTokensScript,
1458
- "getRemainingHash",
1499
+ SCRIPTS.singleRegion.tokenBucket.getRemaining,
1459
1500
  [identifier],
1460
1501
  [maxTokens]
1461
1502
  );
@@ -1473,8 +1514,7 @@ var RegionRatelimit = class extends Ratelimit {
1473
1514
  }
1474
1515
  await safeEval(
1475
1516
  ctx,
1476
- resetScript,
1477
- "resetHash",
1517
+ RESET_SCRIPT,
1478
1518
  [pattern],
1479
1519
  [null]
1480
1520
  );
@@ -1522,8 +1562,7 @@ var RegionRatelimit = class extends Ratelimit {
1522
1562
  const success = cachedTokensAfterUpdate < tokens;
1523
1563
  const pending = success ? safeEval(
1524
1564
  ctx,
1525
- cachedFixedWindowLimitScript,
1526
- "limitHash",
1565
+ SCRIPTS.singleRegion.cachedFixedWindow.limit,
1527
1566
  [key],
1528
1567
  [windowDuration, incrementBy]
1529
1568
  ) : Promise.resolve();
@@ -1537,8 +1576,7 @@ var RegionRatelimit = class extends Ratelimit {
1537
1576
  }
1538
1577
  const usedTokensAfterUpdate = await safeEval(
1539
1578
  ctx,
1540
- cachedFixedWindowLimitScript,
1541
- "limitHash",
1579
+ SCRIPTS.singleRegion.cachedFixedWindow.limit,
1542
1580
  [key],
1543
1581
  [windowDuration, incrementBy]
1544
1582
  );
@@ -1568,8 +1606,7 @@ var RegionRatelimit = class extends Ratelimit {
1568
1606
  }
1569
1607
  const usedTokens = await safeEval(
1570
1608
  ctx,
1571
- cachedFixedWindowRemainingTokenScript,
1572
- "getRemainingHash",
1609
+ SCRIPTS.singleRegion.cachedFixedWindow.getRemaining,
1573
1610
  [key],
1574
1611
  [null]
1575
1612
  );
@@ -1588,8 +1625,7 @@ var RegionRatelimit = class extends Ratelimit {
1588
1625
  const pattern = [identifier, "*"].join(":");
1589
1626
  await safeEval(
1590
1627
  ctx,
1591
- resetScript,
1592
- "resetHash",
1628
+ RESET_SCRIPT,
1593
1629
  [pattern],
1594
1630
  [null]
1595
1631
  );