@daiso-tech/core 0.43.2 → 0.44.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 (96) hide show
  1. package/README.md +2 -2
  2. package/dist/circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/circuit-breaker-state-manager.d.ts +2 -2
  3. package/dist/circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/circuit-breaker-state-manager.js +1 -1
  4. package/dist/circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/circuit-breaker-state-manager.js.map +1 -1
  5. package/dist/circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/circuit-breaker-storage.d.ts +2 -2
  6. package/dist/circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/circuit-breaker-storage.js +1 -1
  7. package/dist/circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/circuit-breaker-storage.js.map +1 -1
  8. package/dist/circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/database-circuit-breaker-adapter.js +2 -2
  9. package/dist/circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/database-circuit-breaker-adapter.js.map +1 -1
  10. package/dist/circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/{circuit-breaker-policy.d.ts → internal-circuit-breaker-policy.d.ts} +1 -1
  11. package/dist/circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/{circuit-breaker-policy.js → internal-circuit-breaker-policy.js} +2 -2
  12. package/dist/circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/internal-circuit-breaker-policy.js.map +1 -0
  13. package/dist/circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/types.d.ts +1 -1
  14. package/dist/circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/types.js +1 -1
  15. package/dist/circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/types.js.map +1 -1
  16. package/dist/circuit-breaker/implementations/adapters/redis-circuit-breaker-adapter/lua/circuit-breaker-factory-lua.js +2 -2
  17. package/dist/circuit-breaker/implementations/adapters/redis-circuit-breaker-adapter/lua/circuit-breaker-factory-lua.js.map +1 -1
  18. package/dist/circuit-breaker/implementations/adapters/redis-circuit-breaker-adapter/lua/circuit-breaker-state-manager-lua.js +1 -1
  19. package/dist/circuit-breaker/implementations/adapters/redis-circuit-breaker-adapter/lua/circuit-breaker-storage-lua.d.ts +1 -1
  20. package/dist/circuit-breaker/implementations/adapters/redis-circuit-breaker-adapter/lua/circuit-breaker-storage-lua.js +1 -1
  21. package/dist/circuit-breaker/implementations/adapters/redis-circuit-breaker-adapter/lua/{circuit-breaker-policy-lua.js → internal-circuit-breaker-policy-lua.js} +2 -2
  22. package/dist/circuit-breaker/implementations/adapters/redis-circuit-breaker-adapter/lua/internal-circuit-breaker-policy-lua.js.map +1 -0
  23. package/dist/circuit-breaker/implementations/adapters/redis-circuit-breaker-adapter/redis-circuit-breaker-adapter.d.ts +2 -2
  24. package/dist/circuit-breaker/implementations/adapters/redis-circuit-breaker-adapter/redis-circuit-breaker-adapter.js +5 -5
  25. package/dist/circuit-breaker/implementations/adapters/redis-circuit-breaker-adapter/redis-circuit-breaker-adapter.js.map +1 -1
  26. package/dist/circuit-breaker/implementations/test-utilities/consecutive-breaker.test-suite.d.ts +2 -2
  27. package/dist/circuit-breaker/implementations/test-utilities/consecutive-breaker.test-suite.js +2 -1
  28. package/dist/circuit-breaker/implementations/test-utilities/consecutive-breaker.test-suite.js.map +1 -1
  29. package/dist/circuit-breaker/implementations/test-utilities/count-breaker.test-suite.d.ts +2 -2
  30. package/dist/circuit-breaker/implementations/test-utilities/count-breaker.test-suite.js +2 -1
  31. package/dist/circuit-breaker/implementations/test-utilities/count-breaker.test-suite.js.map +1 -1
  32. package/dist/circuit-breaker/implementations/test-utilities/sampling-breaker.test-suite.d.ts +2 -2
  33. package/dist/circuit-breaker/implementations/test-utilities/sampling-breaker.test-suite.js +2 -1
  34. package/dist/circuit-breaker/implementations/test-utilities/sampling-breaker.test-suite.js.map +1 -1
  35. package/dist/event-bus/implementations/derivables/event-bus-factory/event-bus-factory.d.ts +0 -2
  36. package/dist/event-bus/implementations/derivables/event-bus-factory/event-bus-factory.js +0 -2
  37. package/dist/event-bus/implementations/derivables/event-bus-factory/event-bus-factory.js.map +1 -1
  38. package/dist/rate-limiter/contracts/rate-limiter-adapter.contract.d.ts +2 -2
  39. package/dist/rate-limiter/contracts/rate-limiter-adapter.contract.js +1 -1
  40. package/dist/rate-limiter/contracts/rate-limiter-adapter.contract.js.map +1 -1
  41. package/dist/rate-limiter/contracts/rate-limiter-state.contract.d.ts +13 -3
  42. package/dist/rate-limiter/contracts/rate-limiter-state.contract.js +2 -1
  43. package/dist/rate-limiter/contracts/rate-limiter-state.contract.js.map +1 -1
  44. package/dist/rate-limiter/implementations/adapters/database-rate-limiter-adapter/database-rate-limiter-adapter.js +18 -16
  45. package/dist/rate-limiter/implementations/adapters/database-rate-limiter-adapter/database-rate-limiter-adapter.js.map +1 -1
  46. package/dist/rate-limiter/implementations/adapters/database-rate-limiter-adapter/{rate-limiter-policy.d.ts → internal-rate-limiter-policy.d.ts} +3 -3
  47. package/dist/rate-limiter/implementations/adapters/database-rate-limiter-adapter/{rate-limiter-policy.js → internal-rate-limiter-policy.js} +10 -9
  48. package/dist/rate-limiter/implementations/adapters/database-rate-limiter-adapter/internal-rate-limiter-policy.js.map +1 -0
  49. package/dist/rate-limiter/implementations/adapters/database-rate-limiter-adapter/rate-limiter-state-manager.d.ts +2 -2
  50. package/dist/rate-limiter/implementations/adapters/database-rate-limiter-adapter/rate-limiter-state-manager.js +1 -1
  51. package/dist/rate-limiter/implementations/adapters/database-rate-limiter-adapter/rate-limiter-state-manager.js.map +1 -1
  52. package/dist/rate-limiter/implementations/adapters/database-rate-limiter-adapter/rate-limiter-storage.d.ts +5 -4
  53. package/dist/rate-limiter/implementations/adapters/database-rate-limiter-adapter/rate-limiter-storage.js +27 -18
  54. package/dist/rate-limiter/implementations/adapters/database-rate-limiter-adapter/rate-limiter-storage.js.map +1 -1
  55. package/dist/rate-limiter/implementations/adapters/no-op-rate-limiter-adapter/no-op-rate-limiter-adapter.js +3 -2
  56. package/dist/rate-limiter/implementations/adapters/no-op-rate-limiter-adapter/no-op-rate-limiter-adapter.js.map +1 -1
  57. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/fixed-window-limiter-lua.d.ts +1 -1
  58. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/fixed-window-limiter-lua.js +2 -2
  59. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/{rate-limiter-policy-lua.js → internal-rate-limiter-policy-lua.js} +38 -20
  60. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/internal-rate-limiter-policy-lua.js.map +1 -0
  61. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-factory-lua.js +3 -3
  62. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-factory-lua.js.map +1 -1
  63. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-lua.d.ts +1 -1
  64. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-lua.js +21 -5
  65. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-lua.js.map +1 -1
  66. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-state-manager-lua.js +1 -1
  67. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-storage-lua.js +41 -24
  68. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-storage-lua.js.map +1 -1
  69. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/redis-rate-limiter-adapter.d.ts +8 -3
  70. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/redis-rate-limiter-adapter.js +34 -17
  71. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/redis-rate-limiter-adapter.js.map +1 -1
  72. package/dist/rate-limiter/implementations/derivables/rate-limiter-provider/rate-limiter-provider.d.ts +12 -3
  73. package/dist/rate-limiter/implementations/derivables/rate-limiter-provider/rate-limiter-provider.js +4 -4
  74. package/dist/rate-limiter/implementations/derivables/rate-limiter-provider/rate-limiter-provider.js.map +1 -1
  75. package/dist/rate-limiter/implementations/derivables/rate-limiter-provider/rate-limiter.js +10 -16
  76. package/dist/rate-limiter/implementations/derivables/rate-limiter-provider/rate-limiter.js.map +1 -1
  77. package/dist/rate-limiter/implementations/derivables/rate-limiter-provider-factory/database-rate-limiter-provider-factory.d.ts +1 -1
  78. package/dist/rate-limiter/implementations/derivables/rate-limiter-provider-factory/database-rate-limiter-provider-factory.js +2 -2
  79. package/dist/rate-limiter/implementations/derivables/rate-limiter-provider-factory/database-rate-limiter-provider-factory.js.map +1 -1
  80. package/dist/rate-limiter/implementations/derivables/rate-limiter-provider-factory/rate-limiter-provider-factory.d.ts +1 -1
  81. package/dist/rate-limiter/implementations/derivables/rate-limiter-provider-factory/rate-limiter-provider-factory.js +2 -2
  82. package/dist/rate-limiter/implementations/derivables/rate-limiter-provider-factory/rate-limiter-provider-factory.js.map +1 -1
  83. package/dist/rate-limiter/implementations/policies/fixed-window-limiter/fixed-window-limiter.js +1 -1
  84. package/dist/rate-limiter/implementations/policies/fixed-window-limiter/fixed-window-limiter.js.map +1 -1
  85. package/dist/rate-limiter/implementations/test-utilities/fixed-window-limiter.test-suite.d.ts +2 -2
  86. package/dist/rate-limiter/implementations/test-utilities/fixed-window-limiter.test-suite.js +171 -11
  87. package/dist/rate-limiter/implementations/test-utilities/fixed-window-limiter.test-suite.js.map +1 -1
  88. package/dist/utilities/functions/invokable.d.ts +0 -31
  89. package/dist/utilities/functions/invokable.js.map +1 -1
  90. package/package.json +1 -1
  91. package/dist/circuit-breaker/implementations/adapters/database-circuit-breaker-adapter/circuit-breaker-policy.js.map +0 -1
  92. package/dist/circuit-breaker/implementations/adapters/redis-circuit-breaker-adapter/lua/circuit-breaker-policy-lua.js.map +0 -1
  93. package/dist/rate-limiter/implementations/adapters/database-rate-limiter-adapter/rate-limiter-policy.js.map +0 -1
  94. package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-policy-lua.js.map +0 -1
  95. /package/dist/circuit-breaker/implementations/adapters/redis-circuit-breaker-adapter/lua/{circuit-breaker-policy-lua.d.ts → internal-circuit-breaker-policy-lua.d.ts} +0 -0
  96. /package/dist/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/{rate-limiter-policy-lua.d.ts → internal-rate-limiter-policy-lua.d.ts} +0 -0
@@ -3,9 +3,8 @@
3
3
  */
4
4
  import {} from "../../../../backoff-policies/_module.js";
5
5
  import { RATE_LIMITER_STATE, } from "../../../../rate-limiter/contracts/_module.js";
6
- import {} from "../../../../rate-limiter/implementations/adapters/database-rate-limiter-adapter/rate-limiter-policy.js";
7
- import { TimeSpan } from "../../../../time-span/implementations/time-span.js";
8
- import { callInvokable } from "../../../../utilities/_module.js";
6
+ import {} from "../../../../rate-limiter/implementations/adapters/database-rate-limiter-adapter/internal-rate-limiter-policy.js";
7
+ import {} from "../../../../utilities/_module.js";
9
8
  /**
10
9
  * @internal
11
10
  */
@@ -19,12 +18,31 @@ export class RateLimiterStorage {
19
18
  this.rateLimiterPolicy = rateLimiterPolicy;
20
19
  this.backoffPolicy = backoffPolicy;
21
20
  }
21
+ static resolveStorageData(data) {
22
+ if (data === null) {
23
+ return null;
24
+ }
25
+ if (data.expiration <= new Date()) {
26
+ return null;
27
+ }
28
+ return data.state;
29
+ }
30
+ toAdapterState(state) {
31
+ const currentDate = new Date();
32
+ return {
33
+ success: state.type === RATE_LIMITER_STATE.ALLOWED,
34
+ attempt: this.rateLimiterPolicy.getAttempts(state, currentDate),
35
+ resetTime: this.rateLimiterPolicy.getExpiration(state, {
36
+ backoffPolicy: this.backoffPolicy,
37
+ currentDate,
38
+ }),
39
+ };
40
+ }
22
41
  async atomicUpdate(args) {
23
42
  const currentDate = new Date();
24
43
  const state = await this.adapter.transaction(async (trx) => {
25
- const data = await this.adapter.find(args.key);
26
- let currentState = data?.state;
27
- if (currentState === undefined) {
44
+ let currentState = RateLimiterStorage.resolveStorageData(await this.adapter.find(args.key));
45
+ if (currentState === null) {
28
46
  currentState = this.rateLimiterPolicy.initialState(currentDate);
29
47
  }
30
48
  const newState = args.update(currentState);
@@ -36,21 +54,12 @@ export class RateLimiterStorage {
36
54
  });
37
55
  return this.toAdapterState(state);
38
56
  }
39
- toAdapterState(state) {
40
- return {
41
- success: state.type === RATE_LIMITER_STATE.ALLOWED,
42
- attempt: state.attempt,
43
- resetTime: state.type === RATE_LIMITER_STATE.ALLOWED
44
- ? null
45
- : TimeSpan.fromTimeSpan(callInvokable(this.backoffPolicy, state.attempt, null)).toEndDate(new Date(state.startedAt)),
46
- };
47
- }
48
57
  async find(key) {
49
- const data = await this.adapter.find(key);
50
- if (data === null) {
58
+ const state = RateLimiterStorage.resolveStorageData(await this.adapter.find(key));
59
+ if (state === null) {
51
60
  return null;
52
61
  }
53
- return this.toAdapterState(data.state);
62
+ return this.toAdapterState(state);
54
63
  }
55
64
  async remove(key) {
56
65
  await this.adapter.remove(key);
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limiter-storage.js","sourceRoot":"","sources":["../../../../../src/rate-limiter/implementations/adapters/database-rate-limiter-adapter/rate-limiter-storage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAsB,MAAM,+BAA+B,CAAC;AACnE,OAAO,EACH,kBAAkB,GAErB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAGN,MAAM,8FAA8F,CAAC;AACtG,OAAO,EAAE,QAAQ,EAAE,MAAM,0CAA0C,CAAC;AACpE,OAAO,EAAE,aAAa,EAAoB,MAAM,wBAAwB,CAAC;AA+BzE;;GAEG;AACH,MAAM,OAAO,kBAAkB;IACV,OAAO,CAEtB;IACe,iBAAiB,CAA8B;IAC/C,aAAa,CAAgB;IAE9C,YAAY,QAA8C;QACtD,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,GAAG,QAAQ,CAAC;QAE/D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,YAAY,CACd,IAAgC;QAEhC,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACvD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/C,IAAI,YAAY,GAAG,IAAI,EAAE,KAAK,CAAC;YAC/B,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;gBAC7B,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;YACpE,CAAC;YAED,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YAE3C,MAAM,GAAG,CAAC,MAAM,CACZ,IAAI,CAAC,GAAG,EACR,QAAQ,EACR,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,QAAQ,EAAE;gBAC3C,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,WAAW;aACd,CAAC,CACL,CAAC;YAEF,OAAO,QAAQ,CAAC;QACpB,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAEO,cAAc,CAClB,KAAoC;QAEpC,OAAO;YACH,OAAO,EAAE,KAAK,CAAC,IAAI,KAAK,kBAAkB,CAAC,OAAO;YAClD,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,SAAS,EACL,KAAK,CAAC,IAAI,KAAK,kBAAkB,CAAC,OAAO;gBACrC,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,QAAQ,CAAC,YAAY,CACjB,aAAa,CACT,IAAI,CAAC,aAAa,EAClB,KAAK,CAAC,OAAO,EACb,IAAI,CACP,CACJ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;SACnD,CAAC;IACN,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW;QAClB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACpB,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;CACJ"}
1
+ {"version":3,"file":"rate-limiter-storage.js","sourceRoot":"","sources":["../../../../../src/rate-limiter/implementations/adapters/database-rate-limiter-adapter/rate-limiter-storage.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@
2
2
  * @module RateLimiter
3
3
  */
4
4
  import {} from "../../../../rate-limiter/contracts/_module.js";
5
+ import { TimeSpan } from "../../../../time-span/implementations/time-span.js";
5
6
  /**
6
7
  * IMPORT_PATH: `"@daiso-tech/core/rate-limiter/no-op-rate-limiter-adapter"`
7
8
  * @group Adapters
@@ -11,7 +12,7 @@ export class NoOpRateLimiterAdapter {
11
12
  return Promise.resolve({
12
13
  success: true,
13
14
  attempt: 1,
14
- resetTime: null,
15
+ resetTime: TimeSpan.fromMilliseconds(1),
15
16
  });
16
17
  }
17
18
  updateState(_key, limit) {
@@ -19,7 +20,7 @@ export class NoOpRateLimiterAdapter {
19
20
  success: true,
20
21
  attempt: 1,
21
22
  limit,
22
- resetTime: null,
23
+ resetTime: TimeSpan.fromMilliseconds(1),
23
24
  });
24
25
  }
25
26
  reset(_key) {
@@ -1 +1 @@
1
- {"version":3,"file":"no-op-rate-limiter-adapter.js","sourceRoot":"","sources":["../../../../../src/rate-limiter/implementations/adapters/no-op-rate-limiter-adapter/no-op-rate-limiter-adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAGN,MAAM,qCAAqC,CAAC;AAE7C;;;GAGG;AACH,MAAM,OAAO,sBAAsB;IAC/B,QAAQ,CAAC,IAAY;QACjB,OAAO,OAAO,CAAC,OAAO,CAAC;YACnB,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,IAAI;SAClB,CAAC,CAAC;IACP,CAAC;IAED,WAAW,CACP,IAAY,EACZ,KAAa;QAEb,OAAO,OAAO,CAAC,OAAO,CAAC;YACnB,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,CAAC;YACV,KAAK;YACL,SAAS,EAAE,IAAI;SAClB,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,IAAY;QACd,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;CACJ"}
1
+ {"version":3,"file":"no-op-rate-limiter-adapter.js","sourceRoot":"","sources":["../../../../../src/rate-limiter/implementations/adapters/no-op-rate-limiter-adapter/no-op-rate-limiter-adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAGN,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,0CAA0C,CAAC;AAEpE;;;GAGG;AACH,MAAM,OAAO,sBAAsB;IAC/B,QAAQ,CAAC,IAAY;QACjB,OAAO,OAAO,CAAC,OAAO,CAAC;YACnB,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC;SAC1C,CAAC,CAAC;IACP,CAAC;IAED,WAAW,CACP,IAAY,EACZ,KAAa;QAEb,OAAO,OAAO,CAAC,OAAO,CAAC;YACnB,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,CAAC;YACV,KAAK;YACL,SAAS,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC;SAC1C,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,IAAY;QACd,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;CACJ"}
@@ -4,4 +4,4 @@
4
4
  /**
5
5
  * @internal
6
6
  */
7
- export declare const fixedWindowLimiterLua = "\n-- @param settings Required<SerializedFixedWindowLimiterSettings>\n-- @return IRateLimiterPolicy<FixedWindowLimiterState>\nlocal function FixedWindowLimiter(settings)\n return {\n -- @param currentDate number\n -- @return FixedWindowLimiterState\n initialMetrics = function(currentDate)\n return {\n attempt = 0,\n lastAttemptAt = currentDate\n }\n end,\n\n -- @param currentMetrics FixedWindowLimiterState\n -- @param limit number\n -- @param currentDate number\n shouldBlock = function(currentMetrics, limit, currentDate)\n local timeSinceLastAttempt = currentDate + currentMetrics.lastAttemptAt\n return timeSinceLastAttempt < settings.window and currentMetrics.attempt >= limit\n end,\n\n -- @param currentMetrics FixedWindowLimiterState\n -- @param _currentDate number\n -- @return number\n getExpiration = function(currentMetrics, _currentDate)\n return settings.window + currentMetrics.lastAttemptAt\n end,\n\n -- @param currentMetrics FixedWindowLimiterState\n -- @param _currentDate number\n -- @return number\n getAttempts = function(currentMetrics, _currentDate)\n return currentMetrics.attempt\n end,\n\n -- @param currentMetrics FixedWindowLimiterState\n -- @param currentDate number\n -- @return FixedWindowLimiterState\n updateMetrics = function(currentMetrics, currentDate)\n return {\n attempt = currentMetrics.attempt + 1,\n lastAttemptAt = currentDate\n }\n end\n }\nend\n";
7
+ export declare const fixedWindowLimiterLua = "\n-- @param settings Required<SerializedFixedWindowLimiterSettings>\n-- @return IRateLimiterPolicy<FixedWindowLimiterState>\nlocal function FixedWindowLimiter(settings)\n return {\n -- @param currentDate number\n -- @return FixedWindowLimiterState\n initialMetrics = function(currentDate)\n return {\n attempt = 0,\n lastAttemptAt = currentDate\n }\n end,\n\n -- @param currentMetrics FixedWindowLimiterState\n -- @param limit number\n -- @param currentDate number\n shouldBlock = function(currentMetrics, limit, currentDate)\n local timeSinceLastAttempt = currentDate - currentMetrics.lastAttemptAt\n return timeSinceLastAttempt < settings.window and currentMetrics.attempt > limit\n end,\n\n -- @param currentMetrics FixedWindowLimiterState\n -- @param _currentDate number\n -- @return number\n getExpiration = function(currentMetrics, _currentDate)\n return settings.window + currentMetrics.lastAttemptAt\n end,\n\n -- @param currentMetrics FixedWindowLimiterState\n -- @param _currentDate number\n -- @return number\n getAttempts = function(currentMetrics, _currentDate)\n return currentMetrics.attempt\n end,\n\n -- @param currentMetrics FixedWindowLimiterState\n -- @param currentDate number\n -- @return FixedWindowLimiterState\n updateMetrics = function(currentMetrics, currentDate)\n return {\n attempt = currentMetrics.attempt + 1,\n lastAttemptAt = currentDate\n }\n end\n }\nend\n";
@@ -22,8 +22,8 @@ local function FixedWindowLimiter(settings)
22
22
  -- @param limit number
23
23
  -- @param currentDate number
24
24
  shouldBlock = function(currentMetrics, limit, currentDate)
25
- local timeSinceLastAttempt = currentDate + currentMetrics.lastAttemptAt
26
- return timeSinceLastAttempt < settings.window and currentMetrics.attempt >= limit
25
+ local timeSinceLastAttempt = currentDate - currentMetrics.lastAttemptAt
26
+ return timeSinceLastAttempt < settings.window and currentMetrics.attempt > limit
27
27
  end,
28
28
 
29
29
  -- @param currentMetrics FixedWindowLimiterState
@@ -8,14 +8,23 @@ import { RATE_LIMITER_STATE } from "../../../../../rate-limiter/contracts/_modul
8
8
  export const rateLimiterPolicyLua = `
9
9
  -- @template TMetrics
10
10
  -- @param rateLimiterPolicy IRateLimiterPolicy
11
- local function RateLimiterPolicy(rateLimiterPolicy)
11
+ local function InternalRateLimiterPolicy(rateLimiterPolicy)
12
12
  return {
13
- -- @param currentState AllowedRateLimiterState<TMetrics>
13
+ -- @param currentDate number
14
+ -- @return AllowedState<TMetrics>
15
+ initialState = function(currentDate)
16
+ return {
17
+ type = "${RATE_LIMITER_STATE.ALLOWED}",
18
+ metrics = rateLimiterPolicy.initialMetrics(currentDate)
19
+ }
20
+ end,
21
+
22
+ -- @param currentState AllowedState<TMetrics>
14
23
  -- @param limit number
15
24
  -- @param currentDate number
16
- -- @return AllowedRateLimiterState<TMetrics>
25
+ -- @return AllRateLimiterState<TMetrics>
17
26
  whenAllowed = function(currentState, limit, currentDate)
18
- if rateLimiterPolicy.shouldBlock(currentState, limit, currentDate) then
27
+ if rateLimiterPolicy.shouldBlock(currentState.metrics, limit, currentDate) then
19
28
  return {
20
29
  type = "${RATE_LIMITER_STATE.BLOCKED}",
21
30
  attempt = 1,
@@ -26,57 +35,66 @@ local function RateLimiterPolicy(rateLimiterPolicy)
26
35
  return currentState
27
36
  end,
28
37
 
29
- -- @param currentState BlockedRateLimiterState
38
+ -- @param currentState BlockedState
30
39
  -- @param settings BackoffPolicySettings
31
40
  -- @return AllRateLimiterState<TMetrics>
32
41
  whenBlocked = function(currentState, settings)
33
- local endDate = settings.backoffPolicy(currentState.attempt, nil) + currentState.startedAt
42
+ local waitTime = settings.backoffPolicy(currentState.attempt, nil)
43
+ local endDate = currentState.startedAt + waitTime
34
44
  local isWaitTimeOver = endDate <= settings.currentDate
35
45
 
36
46
  if isWaitTimeOver then
37
- local currentMetrics = rateLimiterPolicy.initialMetrics(settings.currentDate)
38
47
  return {
39
- attempt = rateLimiterPolicy.getAttempts(currentMetrics, settings.currentDate),
40
48
  type = "${RATE_LIMITER_STATE.ALLOWED}",
41
- metrics = currentMetrics
49
+ metrics = rateLimiterPolicy.initialMetrics(settings.currentDate),
42
50
  }
43
51
  end
44
52
 
45
53
  return currentState
46
54
  end,
47
55
 
48
- -- @param currentState AllowedRateLimiterState<TMetrics>
56
+ -- @param currentState AllowedState<TMetrics>
49
57
  -- @param currentDate number
50
- -- @return AllowedRateLimiterState<TMetrics>
58
+ -- @return AllowedState<TMetrics>
51
59
  trackWhenAllowed = function(currentState, currentDate)
52
60
  return {
53
61
  type = currentState.type,
54
- attempt = currentState.attempt,
55
- metrics = rateLimiterPolicy.updateMetrics(currentState.metrics, currentDate)
62
+ metrics = rateLimiterPolicy.updateMetrics(currentState.metrics, currentDate),
56
63
  }
57
64
  end,
58
65
 
59
- -- @param currentState BlockedRateLimiterState
60
- -- @return BlockedRateLimiterState
66
+ -- @param currentState BlockedState
67
+ -- @return BlockedState
61
68
  trackWhenBlocked = function(currentState)
62
69
  return {
63
70
  type = currentState.type,
64
71
  startedAt = currentState.startedAt,
65
- attempt = currentState.attempt + 1
66
- }
72
+ attempt = currentState.attempt + 1,
73
+ };
67
74
  end,
68
75
 
69
- -- @param AllRateLimiterState<TMetrics>
76
+ -- @param currentState AllRateLimiterState<TMetrics>
70
77
  -- @param settings BackoffPolicySettings
71
78
  -- @return number
72
79
  getExpiration = function(currentState, settings)
73
80
  if currentState.type == "${RATE_LIMITER_STATE.ALLOWED}" then
74
- return rateLimiterPolicy.getExpiration(currentState.metrics, settings.currentDate)
81
+ return rateLimiterPolicy.getExpiration(currentState.metrics, settings.currentDate);
75
82
  end
76
83
 
77
84
  return settings.backoffPolicy(currentState.attempt, nil) + settings.currentDate
85
+ end,
86
+
87
+ -- @param currentState AllRateLimiterState<TMetrics>
88
+ -- @param currentDate number
89
+ -- @return number
90
+ getAttempts = function(currentState, currentDate)
91
+ if currentState.type == "${RATE_LIMITER_STATE.ALLOWED}" then
92
+ return rateLimiterPolicy.getAttempts(currentState.metrics, currentDate);
93
+ end
94
+
95
+ return currentState.attempt
78
96
  end
79
97
  }
80
98
  end
81
99
  `;
82
- //# sourceMappingURL=rate-limiter-policy-lua.js.map
100
+ //# sourceMappingURL=internal-rate-limiter-policy-lua.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal-rate-limiter-policy-lua.js","sourceRoot":"","sources":["../../../../../../src/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/internal-rate-limiter-policy-lua.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAEzE;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;0BASV,kBAAkB,CAAC,OAAO;;;;;;;;;;;;8BAYtB,kBAAkB,CAAC,OAAO;;;;;;;;;;;;;;;;;;;8BAmB1B,kBAAkB,CAAC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uCAgCjB,kBAAkB,CAAC,OAAO;;;;;;;;;;;uCAW1B,kBAAkB,CAAC,OAAO;;;;;;;;CAQhE,CAAC"}
@@ -4,8 +4,8 @@
4
4
  import { BACKOFFS } from "../../../../../backoff-policies/_module.js";
5
5
  import { backoffsLua } from "../../../../../backoff-policies/backoffs-lua.js";
6
6
  import { fixedWindowLimiterLua } from "../../../../../rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/fixed-window-limiter-lua.js";
7
+ import { rateLimiterPolicyLua } from "../../../../../rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/internal-rate-limiter-policy-lua.js";
7
8
  import { rateLimiterLua } from "../../../../../rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-lua.js";
8
- import { rateLimiterPolicyLua } from "../../../../../rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-policy-lua.js";
9
9
  import { rateLimiterStateManagerLua } from "../../../../../rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-state-manager-lua.js";
10
10
  import { rateLimterStorageLua } from "../../../../../rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-storage-lua.js";
11
11
  import { slidingWindowLimiterLua } from "../../../../../rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/sliding-window-limiter-lua.js";
@@ -61,11 +61,11 @@ ${rateLimiterLua}
61
61
  -- @param currentDate number
62
62
  -- @return IRateLimiterAdapter
63
63
  local function rateLimiterFactory(backoffSettings, policySettings, currentDate)
64
- local rateLimiterPolicy = RateLimiterPolicy(rateLimiterPolicyFactory(policySettings))
64
+ local rateLimiterPolicy = InternalRateLimiterPolicy(rateLimiterPolicyFactory(policySettings))
65
65
  local backoffPolicy = backoffPolicyFactory(backoffSettings)
66
66
  local storage = RateLimiterStorage(rateLimiterPolicy, backoffPolicy, currentDate)
67
67
  local stateManager = RateLimiterStateManager(rateLimiterPolicy, backoffPolicy)
68
- return RateLimiter(storage, stateManager)
68
+ return RateLimiter(storage, stateManager, currentDate)
69
69
  end
70
70
  `;
71
71
  //# sourceMappingURL=rate-limiter-factory-lua.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limiter-factory-lua.js","sourceRoot":"","sources":["../../../../../../src/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-factory-lua.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oGAAoG,CAAC;AAC3I,OAAO,EAAE,cAAc,EAAE,MAAM,4FAA4F,CAAC;AAC5H,OAAO,EAAE,oBAAoB,EAAE,MAAM,mGAAmG,CAAC;AACzI,OAAO,EAAE,0BAA0B,EAAE,MAAM,0GAA0G,CAAC;AACtJ,OAAO,EAAE,oBAAoB,EAAE,MAAM,oGAAoG,CAAC;AAC1I,OAAO,EAAE,uBAAuB,EAAE,MAAM,sGAAsG,CAAC;AAC/I,OAAO,EAAE,gBAAgB,EAAE,MAAM,oDAAoD,CAAC;AAEtF;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;EACnC,WAAW;;;;;2BAKc,QAAQ,CAAC,QAAQ;;;;2BAIjB,QAAQ,CAAC,WAAW;;;;2BAIpB,QAAQ,CAAC,MAAM;;;;2BAIf,QAAQ,CAAC,UAAU;;;;;EAK5C,qBAAqB;EACrB,uBAAuB;;;;;2BAKE,gBAAgB,CAAC,YAAY;;;;2BAI7B,gBAAgB,CAAC,cAAc;;;;;EAKxD,oBAAoB;EACpB,oBAAoB;EACpB,0BAA0B;EAC1B,cAAc;;;;;;;;;;;;;CAaf,CAAC"}
1
+ {"version":3,"file":"rate-limiter-factory-lua.js","sourceRoot":"","sources":["../../../../../../src/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-factory-lua.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oGAAoG,CAAC;AAC3I,OAAO,EAAE,oBAAoB,EAAE,MAAM,4GAA4G,CAAC;AAClJ,OAAO,EAAE,cAAc,EAAE,MAAM,4FAA4F,CAAC;AAC5H,OAAO,EAAE,0BAA0B,EAAE,MAAM,0GAA0G,CAAC;AACtJ,OAAO,EAAE,oBAAoB,EAAE,MAAM,oGAAoG,CAAC;AAC1I,OAAO,EAAE,uBAAuB,EAAE,MAAM,sGAAsG,CAAC;AAC/I,OAAO,EAAE,gBAAgB,EAAE,MAAM,oDAAoD,CAAC;AAEtF;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;EACnC,WAAW;;;;;2BAKc,QAAQ,CAAC,QAAQ;;;;2BAIjB,QAAQ,CAAC,WAAW;;;;2BAIpB,QAAQ,CAAC,MAAM;;;;2BAIf,QAAQ,CAAC,UAAU;;;;;EAK5C,qBAAqB;EACrB,uBAAuB;;;;;2BAKE,gBAAgB,CAAC,YAAY;;;;2BAI7B,gBAAgB,CAAC,cAAc;;;;;EAKxD,oBAAoB;EACpB,oBAAoB;EACpB,0BAA0B;EAC1B,cAAc;;;;;;;;;;;;;CAaf,CAAC"}
@@ -1,4 +1,4 @@
1
1
  /**
2
2
  * @module RateLimiter
3
3
  */
4
- export declare const rateLimiterLua = "\n-- @template TMetrics\n-- @param rateLimiterStorage RateLimiterStorage<AllRateLimiterState<TMetrics>>\n-- @param rateLimiterStateManager RateLimiterStateManager<TMetrics>\n-- @param currentDate number\n-- @return IRateLimiterAdapter\nlocal function RateLimiter(rateLimiterStorage, rateLimiterStateManager, currentDate)\n return {\n -- @param key string\n -- @param limit number\n -- @return IRedisJsonRateLimiterState\n updateState = function(key, limit)\n return rateLimiterStorage.atomicUpdate({\n key = key,\n update = function(state)\n return rateLimiterStateManager.updateState(\n limit,\n currentDate\n )(rateLimtierStateManager.track(currentDate)(state))\n end\n })\n end,\n }\nend\n";
4
+ export declare const rateLimiterLua = "\n-- @template TMetrics\n-- @param rateLimiterStorage RateLimiterStorage<AllRateLimiterState<TMetrics>>\n-- @param rateLimiterStateManager RateLimiterStateManager<TMetrics>\n-- @param currentDate number\n-- @return IRateLimiterAdapter\nlocal function RateLimiter(rateLimiterStorage, rateLimiterStateManager, currentDate)\n return {\n -- @param key string\n -- @return IRedisJsonRateLimiterState | null\n getState = function(key)\n local state = rateLimiterStorage.find(key)\n if state == nil or state == cjson.null then\n return nil\n end\n\n return {\n success = state.success,\n attempt = state.attempt,\n resetTime = state.resetTime\n }\n end,\n\n -- @param key string\n -- @param limit number\n -- @return IRedisJsonRateLimiterState\n updateState = function(key, limit)\n local track = rateLimiterStateManager.track(currentDate) \n local updateState = rateLimiterStateManager.updateState(limit, currentDate)\n return rateLimiterStorage.atomicUpdate({\n key = key,\n update = function(prevState)\n local newState1 = track(prevState)\n local newState2 = updateState(newState1)\n return newState2\n end\n })\n end,\n }\nend\n";
@@ -9,17 +9,33 @@ export const rateLimiterLua = `
9
9
  -- @return IRateLimiterAdapter
10
10
  local function RateLimiter(rateLimiterStorage, rateLimiterStateManager, currentDate)
11
11
  return {
12
+ -- @param key string
13
+ -- @return IRedisJsonRateLimiterState | null
14
+ getState = function(key)
15
+ local state = rateLimiterStorage.find(key)
16
+ if state == nil or state == cjson.null then
17
+ return nil
18
+ end
19
+
20
+ return {
21
+ success = state.success,
22
+ attempt = state.attempt,
23
+ resetTime = state.resetTime
24
+ }
25
+ end,
26
+
12
27
  -- @param key string
13
28
  -- @param limit number
14
29
  -- @return IRedisJsonRateLimiterState
15
30
  updateState = function(key, limit)
31
+ local track = rateLimiterStateManager.track(currentDate)
32
+ local updateState = rateLimiterStateManager.updateState(limit, currentDate)
16
33
  return rateLimiterStorage.atomicUpdate({
17
34
  key = key,
18
- update = function(state)
19
- return rateLimiterStateManager.updateState(
20
- limit,
21
- currentDate
22
- )(rateLimtierStateManager.track(currentDate)(state))
35
+ update = function(prevState)
36
+ local newState1 = track(prevState)
37
+ local newState2 = updateState(newState1)
38
+ return newState2
23
39
  end
24
40
  })
25
41
  end,
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limiter-lua.js","sourceRoot":"","sources":["../../../../../../src/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-lua.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;CAwB7B,CAAC"}
1
+ {"version":3,"file":"rate-limiter-lua.js","sourceRoot":"","sources":["../../../../../../src/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-lua.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwC7B,CAAC"}
@@ -7,7 +7,7 @@ import { RATE_LIMITER_STATE } from "../../../../../rate-limiter/contracts/_modul
7
7
  */
8
8
  export const rateLimiterStateManagerLua = `
9
9
  -- @template TMetrics
10
- -- @param rateLimiterPolicy RateLimiterPolicy<TMetrics>
10
+ -- @param rateLimiterPolicy InternalRateLimiterPolicy<TMetrics>
11
11
  -- @param backoffPolicy BackoffPolicy
12
12
  local function RateLimiterStateManager(rateLimiterPolicy, backoffPolicy)
13
13
  return {
@@ -7,7 +7,7 @@ import { RATE_LIMITER_STATE } from "../../../../../rate-limiter/contracts/_modul
7
7
  */
8
8
  export const rateLimterStorageLua = `
9
9
  -- @template TMetrics
10
- -- @param rateLimiterPolicy RateLimiterPolicy<TMetrics>
10
+ -- @param rateLimiterPolicy InternalRateLimiterPolicy<TMetrics>
11
11
  -- @param backoffPolicy BackoffPolicy
12
12
  -- @param currentDate number
13
13
  local function RateLimiterStorage(rateLimiterPolicy, backoffPolicy, currentDate)
@@ -15,14 +15,24 @@ local function RateLimiterStorage(rateLimiterPolicy, backoffPolicy, currentDate)
15
15
  -- @param AllRateLimiterState<TMetrics>
16
16
  -- @return IRedisJsonRateLimiterState
17
17
  local function toAdapterState(state)
18
- local resetTime = state.startedAt
19
- if state.type == "${RATE_LIMITER_STATE.ALLOWED}" then
20
- resetTime = nil
21
- end
22
18
  return {
23
19
  success = state.type == "${RATE_LIMITER_STATE.ALLOWED}",
24
- attempt = state.attempt,
25
- resetTime = resetTime
20
+ attempt = rateLimiterPolicy.getAttempts(state, currentDate),
21
+ resetTime = rateLimiterPolicy.getExpiration(state, {
22
+ backoffPolicy = backoffPolicy,
23
+ currentDate = currentDate
24
+ }),
25
+ }
26
+ end
27
+
28
+ local function toAdapterState2(state)
29
+ return {
30
+ success = state.type == "${RATE_LIMITER_STATE.ALLOWED}",
31
+ attempt = rateLimiterPolicy.getAttempts(state, currentDate),
32
+ resetTime = rateLimiterPolicy.getExpiration(state, {
33
+ backoffPolicy = backoffPolicy,
34
+ currentDate = currentDate
35
+ }),
26
36
  }
27
37
  end
28
38
 
@@ -30,28 +40,35 @@ local function RateLimiterStorage(rateLimiterPolicy, backoffPolicy, currentDate)
30
40
  -- @param args AtomicUpdateArgs<TMetrics>
31
41
  -- @return IRedisJsonRateLimiterState
32
42
  atomicUpdate = function(args)
33
- local data = cjson.decode(redis.call(args.key))
34
- local currentState = nil
35
- if data ~= nil and data ~= cjson.null then
36
- currentState = data.state
37
- end
38
- if currentState == nil or currentState == cjson.null then
39
- currentState = rateLimiterPolicy.initialState(currentDate)
43
+ -- local currentState = cjson.decode(redis.call("get", args.key))
44
+ -- if currentState == nil or currentState == cjson.null then
45
+ -- currentState = rateLimiterPolicy.initialState(currentDate)
46
+ -- end
47
+
48
+ local currentState = rateLimiterPolicy.initialState(currentDate)
49
+ if redis.call("exists", args.key) == 1 then
50
+ currentState = cjson.decode(redis.call("get", args.key))
40
51
  end
41
52
 
42
53
  local newState = args.update(currentState)
43
54
 
44
- redis.call("set", args.key, newState)
45
- redis.call(
46
- "pexpireat",
47
- args.key,
48
- rateLimiterPolicy.getExpiration(newState, {
49
- backoffPolicy = backoffPolicy,
50
- currentDate = currentDate
51
- })
52
- )
53
-
55
+ local expiration = rateLimiterPolicy.getExpiration(newState, {
56
+ backoffPolicy = backoffPolicy,
57
+ currentDate = currentDate
58
+ })
59
+ redis.call("set", args.key, cjson.encode(newState), "pxat", expiration)
60
+
54
61
  return toAdapterState(newState)
62
+ end,
63
+
64
+ -- @param Key
65
+ -- @return IRedisJsonRateLimiterState | null
66
+ find = function(key)
67
+ if redis.call("exists", key) == 0 then
68
+ return nil
69
+ end
70
+
71
+ return toAdapterState(cjson.decode(redis.call("get", key)))
55
72
  end
56
73
  }
57
74
  end
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limiter-storage-lua.js","sourceRoot":"","sources":["../../../../../../src/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-storage-lua.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAEzE;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;4BAWR,kBAAkB,CAAC,OAAO;;;;uCAIf,kBAAkB,CAAC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmChE,CAAC"}
1
+ {"version":3,"file":"rate-limiter-storage-lua.js","sourceRoot":"","sources":["../../../../../../src/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/lua/rate-limiter-storage-lua.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAEzE;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;uCAWG,kBAAkB,CAAC,OAAO;;;;;;;;;;;uCAW1B,kBAAkB,CAAC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6ChE,CAAC"}
@@ -8,9 +8,13 @@ import { type RateLimiterPolicySettingsEnum } from "../../../../rate-limiter/imp
8
8
  declare module "ioredis" {
9
9
  interface RedisCommander<Context> {
10
10
  /**
11
- * @returns {string} {@link IRedisJsonRateLimiterState | `IRedisJsonRateLimiterState | null`} as json string.
11
+ * @returns {string} {@link IRedisJsonRateLimiterState | `IRedisJsonRateLimiterState`} as json string.
12
12
  */
13
13
  daiso_rate_limiter_update_state(key: string, limit: number, backoffSettings: string, policySettings: string, currentDate: number): Result<string, Context>;
14
+ /**
15
+ * @returns {string} {@link IRedisJsonRateLimiterState | `IRedisJsonRateLimiterState | null`} as json string.
16
+ */
17
+ daiso_rate_limiter_get_state(key: string, backoffSettings: string, policySettings: string, currentDate: number): Result<string, Context>;
14
18
  }
15
19
  }
16
20
  /**
@@ -26,7 +30,7 @@ export type RedisRateLimiterAdapterSettings = {
26
30
  * { type: BACKOFFS.EXPONENTIAL }
27
31
  * ```
28
32
  */
29
- backoff?: BackoffSettingsEnum;
33
+ backoffPolicy?: BackoffSettingsEnum;
30
34
  /**
31
35
  * You can choose between different types of predefined circuit breaker policies.
32
36
  * @default
@@ -34,7 +38,7 @@ export type RedisRateLimiterAdapterSettings = {
34
38
  * { type: LIMITER.FIXED_WINDOW }
35
39
  * ```
36
40
  */
37
- policy?: RateLimiterPolicySettingsEnum;
41
+ rateLimiterPolicy?: RateLimiterPolicySettingsEnum;
38
42
  };
39
43
  /**
40
44
  * IMPORT_PATH: `"@daiso-tech/core/rate-limiter/redis-rate-limiter-adapter"`
@@ -57,6 +61,7 @@ export declare class RedisRateLimiterAdapter implements IRateLimiterAdapter {
57
61
  * ```
58
62
  */
59
63
  constructor(settings: RedisRateLimiterAdapterSettings);
64
+ private initGetStateCommand;
60
65
  private initUpdateStateCommmand;
61
66
  getState(key: string): Promise<IRateLimiterAdapterState | null>;
62
67
  updateState(key: string, limit: number): Promise<IRateLimiterAdapterState>;
@@ -28,16 +28,37 @@ export class RedisRateLimiterAdapter {
28
28
  * ```
29
29
  */
30
30
  constructor(settings) {
31
- const { database, backoff = {
31
+ const { database, backoffPolicy = {
32
32
  type: BACKOFFS.EXPONENTIAL,
33
- }, policy = {
33
+ }, rateLimiterPolicy = {
34
34
  type: LIMITER_POLICIES.FIXED_WINDOW,
35
35
  }, } = settings;
36
36
  this.database = database;
37
- this.backoff = resolveBackoffSettingsEnum(backoff);
38
- this.policy = resolveRateLimiterPolicySettings(policy);
37
+ this.backoff = resolveBackoffSettingsEnum(backoffPolicy);
38
+ this.policy = resolveRateLimiterPolicySettings(rateLimiterPolicy);
39
+ this.initGetStateCommand();
39
40
  this.initUpdateStateCommmand();
40
41
  }
42
+ initGetStateCommand() {
43
+ if (typeof this.database.daiso_rate_limiter_get_state === "function") {
44
+ return;
45
+ }
46
+ this.database.defineCommand("daiso_rate_limiter_get_state", {
47
+ numberOfKeys: 1,
48
+ lua: `
49
+ ${rateLimiterFactoryLua}
50
+
51
+ local key = KEYS[1];
52
+ local backoffSettings = cjson.decode(ARGV[1]);
53
+ local policySettings = cjson.decode(ARGV[2]);
54
+ local currentDate = tonumber(ARGV[3]);
55
+
56
+ local rateLimiter = rateLimiterFactory(backoffSettings, policySettings, currentDate)
57
+ local state = rateLimiter.getState(key)
58
+ return cjson.encode(state)
59
+ `,
60
+ });
61
+ }
41
62
  initUpdateStateCommmand() {
42
63
  if (typeof this.database.daiso_rate_limiter_update_state === "function") {
43
64
  return;
@@ -60,19 +81,17 @@ export class RedisRateLimiterAdapter {
60
81
  });
61
82
  }
62
83
  async getState(key) {
63
- const json = await this.database.get(key);
64
- if (json === null) {
84
+ const json = await this.database.daiso_rate_limiter_get_state(key, JSON.stringify(serializeBackoffSettingsEnum(this.backoff)), JSON.stringify(serializeRateLimiterPolicySettingsEnum(this.policy)), Date.now());
85
+ const state = JSON.parse(json);
86
+ if (state === null) {
65
87
  return null;
66
88
  }
67
- const state = JSON.parse(json);
68
89
  return {
69
90
  success: state.success,
70
91
  attempt: state.attempt,
71
- resetTime: state.resetTime === -1
72
- ? null
73
- : TimeSpan.fromDateRange({
74
- end: new Date(state.resetTime),
75
- }),
92
+ resetTime: TimeSpan.fromDateRange({
93
+ end: new Date(state.resetTime),
94
+ }),
76
95
  };
77
96
  }
78
97
  async updateState(key, limit) {
@@ -81,11 +100,9 @@ export class RedisRateLimiterAdapter {
81
100
  return {
82
101
  success: state.success,
83
102
  attempt: state.attempt,
84
- resetTime: state.resetTime === -1
85
- ? null
86
- : TimeSpan.fromDateRange({
87
- end: new Date(state.resetTime),
88
- }),
103
+ resetTime: TimeSpan.fromDateRange({
104
+ end: new Date(state.resetTime),
105
+ }),
89
106
  };
90
107
  }
91
108
  async reset(key) {
@@ -1 +1 @@
1
- {"version":3,"file":"redis-rate-limiter-adapter.js","sourceRoot":"","sources":["../../../../../src/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/redis-rate-limiter-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"redis-rate-limiter-adapter.js","sourceRoot":"","sources":["../../../../../src/rate-limiter/implementations/adapters/redis-rate-limiter-adapter/redis-rate-limiter-adapter.ts"],"names":[],"mappings":"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"}