tiny-essentials 1.8.4 → 1.9.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 (143) hide show
  1. package/dist/TinyBasicsEs.js +30 -0
  2. package/dist/TinyBasicsEs.min.js +1 -1
  3. package/dist/TinyEssentials.js +229 -0
  4. package/dist/TinyEssentials.min.js +1 -1
  5. package/dist/TinyRateLimiter.js +236 -0
  6. package/dist/TinyRateLimiter.min.js +1 -0
  7. package/dist/legacy/crypto/decrypt.cjs +1 -1
  8. package/dist/legacy/crypto/decrypt.mjs +3 -3
  9. package/dist/legacy/crypto/default.cjs +0 -2
  10. package/dist/legacy/crypto/default.mjs +0 -1
  11. package/dist/legacy/crypto/encrypt.cjs +1 -2
  12. package/dist/legacy/crypto/encrypt.mjs +3 -4
  13. package/dist/legacy/crypto/index.cjs +1 -1
  14. package/dist/legacy/crypto/index.mjs +0 -1
  15. package/dist/legacy/firebase/database/presence.cjs +4 -1
  16. package/dist/legacy/firebase/database/presence.d.mts +3 -0
  17. package/dist/legacy/firebase/database/presence.mjs +4 -1
  18. package/dist/legacy/firebase/databaseLogger.cjs +2 -2
  19. package/dist/legacy/firebase/discord/get/cookie-session.cjs +2 -2
  20. package/dist/legacy/firebase/discord/get/errorValidator.cjs +2 -2
  21. package/dist/legacy/firebase/discord/http/login.cjs +7 -7
  22. package/dist/legacy/firebase/discord/http/logout.cjs +4 -4
  23. package/dist/legacy/firebase/discord/http/redirect.cjs +7 -7
  24. package/dist/legacy/firebase/discord/http/refreshToken.cjs +5 -5
  25. package/dist/legacy/firebase/discord/template/cookie-session.cjs +8 -8
  26. package/dist/legacy/firebase/logger.cjs +7 -7
  27. package/dist/legacy/firebase/mySQL.cjs +1 -0
  28. package/dist/legacy/firebase/mysqlConnector/sameUser.cjs +2 -2
  29. package/dist/legacy/get/countObj.cjs +2 -22
  30. package/dist/legacy/get/countObj.d.mts +2 -11
  31. package/dist/legacy/get/countObj.mjs +2 -22
  32. package/dist/legacy/get/decimalColor.cjs +10 -11
  33. package/dist/legacy/get/decimalColor.mjs +10 -10
  34. package/dist/legacy/get/objType.cjs +2 -40
  35. package/dist/legacy/get/objType.d.mts +2 -19
  36. package/dist/legacy/get/objType.mjs +2 -41
  37. package/dist/legacy/get/pagination.cjs +30 -25
  38. package/dist/legacy/get/pagination.d.mts +29 -12
  39. package/dist/legacy/get/pagination.mjs +30 -23
  40. package/dist/legacy/get/queryUrlByName.cjs +0 -2
  41. package/dist/legacy/get/queryUrlByName.mjs +0 -1
  42. package/dist/legacy/get/queryUrlJSON.cjs +2 -2
  43. package/dist/legacy/get/queryUrlJSON.mjs +1 -1
  44. package/dist/legacy/get/super_string_filter.cjs +14 -6
  45. package/dist/legacy/get/super_string_filter.mjs +11 -1
  46. package/dist/legacy/get/versionCheck.cjs +18 -19
  47. package/dist/legacy/get/versionCheck.d.mts +15 -5
  48. package/dist/legacy/get/versionCheck.mjs +16 -16
  49. package/dist/legacy/http/HTTP-1.0.cjs +2 -4
  50. package/dist/legacy/http/HTTP-1.0.d.mts +1 -1
  51. package/dist/legacy/http/HTTP-1.0.mjs +2 -3
  52. package/dist/legacy/http/auth.cjs +2 -4
  53. package/dist/legacy/http/auth.d.mts +4 -4
  54. package/dist/legacy/http/auth.mjs +2 -3
  55. package/dist/legacy/http/check_domain.cjs +15 -9
  56. package/dist/legacy/http/check_domain.d.mts +5 -6
  57. package/dist/legacy/http/check_domain.mjs +12 -8
  58. package/dist/legacy/http/csrfTokenAnalyze.cjs +5 -4
  59. package/dist/legacy/http/csrfTokenAnalyze.d.mts +3 -3
  60. package/dist/legacy/http/csrfTokenAnalyze.mjs +7 -4
  61. package/dist/legacy/http/domainValidator.cjs +13 -9
  62. package/dist/legacy/http/domainValidator.d.mts +15 -6
  63. package/dist/legacy/http/domainValidator.mjs +11 -6
  64. package/dist/legacy/http/errorsCallback.cjs +10 -4
  65. package/dist/legacy/http/errorsCallback.d.mts +13 -3
  66. package/dist/legacy/http/errorsCallback.mjs +12 -4
  67. package/dist/legacy/http/fetch/json.cjs +1 -3
  68. package/dist/legacy/http/fetch/json.mjs +1 -1
  69. package/dist/legacy/http/fetch/text.cjs +1 -3
  70. package/dist/legacy/http/fetch/text.mjs +1 -1
  71. package/dist/legacy/http/fileCache.cjs +2 -5
  72. package/dist/legacy/http/fileCache.d.mts +3 -3
  73. package/dist/legacy/http/fileCache.mjs +2 -3
  74. package/dist/legacy/http/getDomainURL.cjs +4 -7
  75. package/dist/legacy/http/getDomainURL.d.mts +2 -2
  76. package/dist/legacy/http/getDomainURL.mjs +4 -5
  77. package/dist/legacy/http/userIP.cjs +7 -5
  78. package/dist/legacy/http/userIP.d.mts +10 -4
  79. package/dist/legacy/http/userIP.mjs +7 -4
  80. package/dist/legacy/index.cjs +3 -4
  81. package/dist/legacy/index.d.mts +8 -9
  82. package/dist/legacy/libs/arraySortPositions.cjs +1 -3
  83. package/dist/legacy/libs/arraySortPositions.d.mts +2 -2
  84. package/dist/legacy/libs/arraySortPositions.mjs +1 -2
  85. package/dist/legacy/libs/capitalize.cjs +0 -2
  86. package/dist/legacy/libs/capitalize.mjs +0 -1
  87. package/dist/legacy/libs/convertBytes.cjs +1 -3
  88. package/dist/legacy/libs/convertBytes.mjs +1 -2
  89. package/dist/legacy/libs/custom_module_loader.cjs +13 -9
  90. package/dist/legacy/libs/custom_module_loader.d.mts +1 -1
  91. package/dist/legacy/libs/custom_module_loader.mjs +10 -5
  92. package/dist/legacy/libs/dice.cjs +0 -2
  93. package/dist/legacy/libs/dice.mjs +0 -1
  94. package/dist/legacy/libs/markdown.cjs +13 -4
  95. package/dist/legacy/libs/markdown.d.mts +7 -71
  96. package/dist/legacy/libs/markdown.mjs +13 -3
  97. package/dist/legacy/libs/percentage.cjs +0 -2
  98. package/dist/legacy/libs/percentage.mjs +0 -1
  99. package/dist/legacy/libs/regex/getLetter.cjs +0 -2
  100. package/dist/legacy/libs/regex/getLetter.mjs +0 -1
  101. package/dist/legacy/libs/rule3.cjs +0 -2
  102. package/dist/legacy/libs/rule3.mjs +0 -1
  103. package/dist/legacy/momentjs/getAge.cjs +0 -3
  104. package/dist/legacy/momentjs/getAge.d.mts +1 -0
  105. package/dist/legacy/momentjs/getAge.mjs +0 -1
  106. package/dist/legacy/momentjs/index.cjs +1 -1
  107. package/dist/legacy/momentjs/index.mjs +0 -1
  108. package/dist/legacy/momentjs/timeDuration.cjs +1 -3
  109. package/dist/legacy/momentjs/timeDuration.d.mts +1 -0
  110. package/dist/legacy/momentjs/timeDuration.mjs +1 -1
  111. package/dist/legacy/socket.io/antiFlood/index.cjs +1 -1
  112. package/dist/legacy/socket.io/antiFlood/index.mjs +0 -1
  113. package/dist/legacy/socket.io/antiFlood/install.cjs +3 -5
  114. package/dist/legacy/socket.io/antiFlood/install.d.mts +5 -3
  115. package/dist/legacy/socket.io/antiFlood/install.mjs +3 -3
  116. package/dist/legacy/socket.io/antiFlood/verify.cjs +10 -6
  117. package/dist/legacy/socket.io/antiFlood/verify.d.mts +8 -3
  118. package/dist/legacy/socket.io/antiFlood/verify.mjs +10 -6
  119. package/dist/legacy/socket.io/cookie-session.cjs +1 -2
  120. package/dist/legacy/socket.io/cookie-session.mjs +1 -1
  121. package/dist/legacy/socket.io/discord.cjs +0 -3
  122. package/dist/legacy/socket.io/discord.mjs +0 -1
  123. package/dist/legacy/socket.io/index.cjs +0 -3
  124. package/dist/legacy/socket.io/index.mjs +0 -1
  125. package/dist/v1/basics/index.cjs +2 -0
  126. package/dist/v1/basics/index.d.mts +2 -1
  127. package/dist/v1/basics/index.mjs +2 -1
  128. package/dist/v1/build/TinyRateLimiter.cjs +7 -0
  129. package/dist/v1/build/TinyRateLimiter.d.mts +3 -0
  130. package/dist/v1/build/TinyRateLimiter.mjs +2 -0
  131. package/dist/v1/index.cjs +4 -0
  132. package/dist/v1/index.d.mts +3 -1
  133. package/dist/v1/index.mjs +3 -1
  134. package/dist/v1/libs/TinyRateLimit.cjs +196 -0
  135. package/dist/v1/libs/TinyRateLimit.d.mts +86 -0
  136. package/dist/v1/libs/TinyRateLimit.mjs +171 -0
  137. package/dist/v1/libs/TinyRateLimiter.cjs +197 -0
  138. package/dist/v1/libs/TinyRateLimiter.d.mts +86 -0
  139. package/dist/v1/libs/TinyRateLimiter.mjs +173 -0
  140. package/docs/README.md +1 -0
  141. package/docs/basics/array.md +61 -0
  142. package/docs/libs/TinyRateLimiter.md +156 -0
  143. package/package.json +9 -2
@@ -1,4 +1,3 @@
1
- // @ts-nocheck
2
1
  /**
3
2
  * Rule of Three utility.
4
3
  * Performs direct or inverse proportional calculation.
@@ -2,9 +2,6 @@
2
2
 
3
3
  var moment = require('moment');
4
4
 
5
- // @ts-nocheck
6
-
7
-
8
5
  /**
9
6
  * Calculates the age based on the given date.
10
7
  *
@@ -6,4 +6,5 @@
6
6
  * @returns {number|null} The age in years, or null if `timeData` is not provided.
7
7
  */
8
8
  export default function getAge(timeData?: number | string, now?: moment.Moment | null): number | null;
9
+ import moment from 'moment';
9
10
  //# sourceMappingURL=getAge.d.mts.map
@@ -1,4 +1,3 @@
1
- // @ts-nocheck
2
1
  import moment from 'moment';
3
2
  /**
4
3
  * Calculates the age based on the given date.
@@ -3,7 +3,7 @@
3
3
  var timeDuration = require('./timeDuration.cjs');
4
4
  var getAge = require('./getAge.cjs');
5
5
 
6
- // @ts-nocheck
6
+
7
7
 
8
8
  exports.timeDuration = timeDuration;
9
9
  exports.getAge = getAge;
@@ -1,4 +1,3 @@
1
- // @ts-nocheck
2
1
  import timeDuration from './timeDuration.mjs';
3
2
  import getAge from './getAge.mjs';
4
3
  export { timeDuration, getAge };
@@ -2,9 +2,6 @@
2
2
 
3
3
  var moment = require('moment');
4
4
 
5
- // @ts-nocheck
6
-
7
-
8
5
  /**
9
6
  * Calculates the time duration between the current time and a given time offset.
10
7
  *
@@ -19,6 +16,7 @@ function timeDuration(timeData = 0, durationType = 'asSeconds', now = null) {
19
16
  if (!now) now = moment();
20
17
 
21
18
  var duration = moment.duration(now.clone().add(timeData, 'milliseconds').diff(now.clone()));
19
+ // @ts-ignore
22
20
  const result = duration[durationType]();
23
21
 
24
22
  // Complete
@@ -7,4 +7,5 @@
7
7
  * @returns {number|null} The calculated duration in the specified unit (default: seconds), or `null` if `timeData` is not provided.
8
8
  */
9
9
  export default function timeDuration(timeData?: number, durationType?: string, now?: moment.Moment | null): number | null;
10
+ import moment from 'moment';
10
11
  //# sourceMappingURL=timeDuration.d.mts.map
@@ -1,4 +1,3 @@
1
- // @ts-nocheck
2
1
  import moment from 'moment';
3
2
  /**
4
3
  * Calculates the time duration between the current time and a given time offset.
@@ -14,6 +13,7 @@ export default function timeDuration(timeData = 0, durationType = 'asSeconds', n
14
13
  if (!now)
15
14
  now = moment();
16
15
  var duration = moment.duration(now.clone().add(timeData, 'milliseconds').diff(now.clone()));
16
+ // @ts-ignore
17
17
  const result = duration[durationType]();
18
18
  // Complete
19
19
  return result;
@@ -3,7 +3,7 @@
3
3
  var install = require('./install.cjs');
4
4
  var verify = require('./verify.cjs');
5
5
 
6
- // @ts-nocheck
6
+
7
7
 
8
8
  exports.install = install;
9
9
  exports.verify = verify;
@@ -1,4 +1,3 @@
1
- // @ts-nocheck
2
1
  import install from './install.mjs';
3
2
  import verify from './verify.mjs';
4
3
  export { verify, install };
@@ -2,21 +2,19 @@
2
2
 
3
3
  var userIP = require('../../http/userIP.cjs');
4
4
 
5
- // @ts-nocheck
6
-
7
-
8
5
  /**
9
6
  * Installs the authorization middleware for socket connections.
10
7
  *
11
8
  * This middleware checks the user's IP address and allows or denies the socket connection based on whether
12
9
  * the IP is in the block list or not.
13
10
  *
14
- * @param {Record<string, any>} io - The Socket.IO server instance.
15
- * @param {Record<string, any>} ioCache - The cache object containing blocked IPs.
11
+ * @param {*} io - The Socket.IO server instance.
12
+ * @param {Object} ioCache - The cache object containing blocked IPs.
16
13
  * @param {Array<*>} ioCache.blocklick - The list of blocked IP addresses.
17
14
  * @returns {void} This function does not return a value, it just sets the authorization logic for socket connections.
18
15
  */
19
16
  function install(io, ioCache) {
17
+ // @ts-ignore
20
18
  io.set('authorization', function (socket, callback) {
21
19
  // Get User IP
22
20
  const ip = userIP(socket.handshake);
@@ -4,10 +4,12 @@
4
4
  * This middleware checks the user's IP address and allows or denies the socket connection based on whether
5
5
  * the IP is in the block list or not.
6
6
  *
7
- * @param {Record<string, any>} io - The Socket.IO server instance.
8
- * @param {Record<string, any>} ioCache - The cache object containing blocked IPs.
7
+ * @param {*} io - The Socket.IO server instance.
8
+ * @param {Object} ioCache - The cache object containing blocked IPs.
9
9
  * @param {Array<*>} ioCache.blocklick - The list of blocked IP addresses.
10
10
  * @returns {void} This function does not return a value, it just sets the authorization logic for socket connections.
11
11
  */
12
- export default function install(io: Record<string, any>, ioCache: Record<string, any>): void;
12
+ export default function install(io: any, ioCache: {
13
+ blocklick: Array<any>;
14
+ }): void;
13
15
  //# sourceMappingURL=install.d.mts.map
@@ -1,4 +1,3 @@
1
- // @ts-nocheck
2
1
  import userIp from '../../http/userIP.mjs';
3
2
  /**
4
3
  * Installs the authorization middleware for socket connections.
@@ -6,12 +5,13 @@ import userIp from '../../http/userIP.mjs';
6
5
  * This middleware checks the user's IP address and allows or denies the socket connection based on whether
7
6
  * the IP is in the block list or not.
8
7
  *
9
- * @param {Record<string, any>} io - The Socket.IO server instance.
10
- * @param {Record<string, any>} ioCache - The cache object containing blocked IPs.
8
+ * @param {*} io - The Socket.IO server instance.
9
+ * @param {Object} ioCache - The cache object containing blocked IPs.
11
10
  * @param {Array<*>} ioCache.blocklick - The list of blocked IP addresses.
12
11
  * @returns {void} This function does not return a value, it just sets the authorization logic for socket connections.
13
12
  */
14
13
  export default function install(io, ioCache) {
14
+ // @ts-ignore
15
15
  io.set('authorization', function (socket, callback) {
16
16
  // Get User IP
17
17
  const ip = userIp(socket.handshake);
@@ -2,10 +2,14 @@
2
2
 
3
3
  var userIP = require('../../http/userIP.cjs');
4
4
 
5
- // @ts-nocheck
5
+ /** @typedef {Record<string, { timeout: number, tries: number }>} FloodTimeout */
6
6
 
7
+ /**
8
+ * Panel
9
+ *
10
+ * @type {FloodTimeout}
11
+ */
7
12
 
8
- // Panel
9
13
  const floodPanel = {};
10
14
 
11
15
  /**
@@ -27,14 +31,14 @@ setInterval(function () {
27
31
  * If the attempts exceed a threshold, the IP is temporarily banned and disconnected.
28
32
  *
29
33
  * @param {Record<string, any>} socket - The socket object representing the connection.
30
- * @param {Record<string, any>} ioCache - The cache object that holds the blocklist and flood panel data.
34
+ * @param {Object} ioCache - The cache object that holds the blocklist and flood panel data.
31
35
  * @param {Array<*>} ioCache.blocklick - The list of blocked IPs.
32
- * @param {Record<string, any>} floodPanel - The object tracking flooding attempts and timeouts for each IP.
33
36
  * @returns {void} This function does not return anything, it modifies the floodPanel and blocklist.
34
37
  */
35
38
  function verify(socket, ioCache) {
36
39
  // Get User IP
37
- const ip = userIP(socket.handshake);
40
+ const ipData = userIP(socket.handshake);
41
+ const ip = ipData.value ? ipData.value[0] : '';
38
42
 
39
43
  /**
40
44
  * Verifies the IP for flooding attempts and manages timeout and blocklist.
@@ -71,7 +75,7 @@ function verify(socket, ioCache) {
71
75
 
72
76
  // Catch-all Event Listener
73
77
  var onevent = socket.onevent;
74
- socket.onevent = function (packet) {
78
+ socket.onevent = function (/** @type {{ data: string[]; }} */ packet) {
75
79
  var args = packet.data || [];
76
80
  onevent.call(this, packet); // original call
77
81
  packet.data = ['*'].concat(args);
@@ -5,10 +5,15 @@
5
5
  * If the attempts exceed a threshold, the IP is temporarily banned and disconnected.
6
6
  *
7
7
  * @param {Record<string, any>} socket - The socket object representing the connection.
8
- * @param {Record<string, any>} ioCache - The cache object that holds the blocklist and flood panel data.
8
+ * @param {Object} ioCache - The cache object that holds the blocklist and flood panel data.
9
9
  * @param {Array<*>} ioCache.blocklick - The list of blocked IPs.
10
- * @param {Record<string, any>} floodPanel - The object tracking flooding attempts and timeouts for each IP.
11
10
  * @returns {void} This function does not return anything, it modifies the floodPanel and blocklist.
12
11
  */
13
- export default function verify(socket: Record<string, any>, ioCache: Record<string, any>): void;
12
+ export default function verify(socket: Record<string, any>, ioCache: {
13
+ blocklick: Array<any>;
14
+ }): void;
15
+ export type FloodTimeout = Record<string, {
16
+ timeout: number;
17
+ tries: number;
18
+ }>;
14
19
  //# sourceMappingURL=verify.d.mts.map
@@ -1,6 +1,10 @@
1
- // @ts-nocheck
2
1
  import userIp from '../../http/userIP.mjs';
3
- // Panel
2
+ /** @typedef {Record<string, { timeout: number, tries: number }>} FloodTimeout */
3
+ /**
4
+ * Panel
5
+ *
6
+ * @type {FloodTimeout}
7
+ */
4
8
  const floodPanel = {};
5
9
  /**
6
10
  * Periodically decrements the timeout for each IP in the flood panel and removes expired entries.
@@ -21,14 +25,14 @@ setInterval(function () {
21
25
  * If the attempts exceed a threshold, the IP is temporarily banned and disconnected.
22
26
  *
23
27
  * @param {Record<string, any>} socket - The socket object representing the connection.
24
- * @param {Record<string, any>} ioCache - The cache object that holds the blocklist and flood panel data.
28
+ * @param {Object} ioCache - The cache object that holds the blocklist and flood panel data.
25
29
  * @param {Array<*>} ioCache.blocklick - The list of blocked IPs.
26
- * @param {Record<string, any>} floodPanel - The object tracking flooding attempts and timeouts for each IP.
27
30
  * @returns {void} This function does not return anything, it modifies the floodPanel and blocklist.
28
31
  */
29
32
  export default function verify(socket, ioCache) {
30
33
  // Get User IP
31
- const ip = userIp(socket.handshake);
34
+ const ipData = userIp(socket.handshake);
35
+ const ip = ipData.value ? ipData.value[0] : '';
32
36
  /**
33
37
  * Verifies the IP for flooding attempts and manages timeout and blocklist.
34
38
  */
@@ -59,7 +63,7 @@ export default function verify(socket, ioCache) {
59
63
  }
60
64
  // Catch-all Event Listener
61
65
  var onevent = socket.onevent;
62
- socket.onevent = function (packet) {
66
+ socket.onevent = function (/** @type {{ data: string[]; }} */ packet) {
63
67
  var args = packet.data || [];
64
68
  onevent.call(this, packet); // original call
65
69
  packet.data = ['*'].concat(args);
@@ -1,7 +1,5 @@
1
1
  'use strict';
2
2
 
3
- // @ts-nocheck
4
-
5
3
  /**
6
4
  * Handles the cookie session for a socket connection by simulating an Express request and response.
7
5
  * This function uses the provided session module to manage session data for the socket connection.
@@ -13,6 +11,7 @@
13
11
  function cookieSession(socket, sessionModule) {
14
12
  return new Promise((resolve) => {
15
13
  // Express Simulator
14
+ /** @type {Record<*,*>} */
16
15
  let req = {
17
16
  connection: { encrypted: false },
18
17
  headers: { cookie: socket.request.headers.cookie },
@@ -1,4 +1,3 @@
1
- // @ts-nocheck
2
1
  /**
3
2
  * Handles the cookie session for a socket connection by simulating an Express request and response.
4
3
  * This function uses the provided session module to manage session data for the socket connection.
@@ -10,6 +9,7 @@
10
9
  export default function cookieSession(socket, sessionModule) {
11
10
  return new Promise((resolve) => {
12
11
  // Express Simulator
12
+ /** @type {Record<*,*>} */
13
13
  let req = {
14
14
  connection: { encrypted: false },
15
15
  headers: { cookie: socket.request.headers.cookie },
@@ -2,9 +2,6 @@
2
2
 
3
3
  var getUser = require('../firebase/discord/api/getUser.cjs');
4
4
 
5
- // @ts-nocheck
6
-
7
-
8
5
  /**
9
6
  * Handles the Discord OAuth2 authentication for a user, stores user data in an in-memory cache,
10
7
  * and manages the user's socket connection and disconnection events.
@@ -1,4 +1,3 @@
1
- // @ts-nocheck
2
1
  import getUser from '../firebase/discord/api/getUser.mjs';
3
2
  /**
4
3
  * Handles the Discord OAuth2 authentication for a user, stores user data in an in-memory cache,
@@ -4,9 +4,6 @@ var index = require('./antiFlood/index.cjs');
4
4
  var discord = require('./discord.cjs');
5
5
  var cookieSession = require('./cookie-session.cjs');
6
6
 
7
- // @ts-nocheck
8
-
9
-
10
7
  const socketIo = {
11
8
  antiFlood: index,
12
9
  'cookie-session': cookieSession,
@@ -1,4 +1,3 @@
1
- // @ts-nocheck
2
1
  import * as antiFlood from './antiFlood/index.mjs';
3
2
  import discord from './discord.mjs';
4
3
  import cookieSession from './cookie-session.mjs';
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var arraySortPositions = require('../../legacy/libs/arraySortPositions.cjs');
3
4
  var replaceAsync = require('../../legacy/libs/replaceAsync.cjs');
4
5
  var array = require('./array.cjs');
5
6
  var clock = require('./clock.cjs');
@@ -9,6 +10,7 @@ var text = require('./text.cjs');
9
10
 
10
11
 
11
12
 
13
+ exports.arraySortPositions = arraySortPositions;
12
14
  exports.asyncReplace = replaceAsync;
13
15
  exports.shuffleArray = array.shuffleArray;
14
16
  exports.formatCustomTimer = clock.formatCustomTimer;
@@ -1,3 +1,4 @@
1
+ import arraySortPositions from '../../legacy/libs/arraySortPositions.mjs';
1
2
  import { formatBytes } from './simpleMath.mjs';
2
3
  import { addAiMarkerShortcut } from './text.mjs';
3
4
  import { extendObjType } from './objFilter.mjs';
@@ -16,5 +17,5 @@ import { getTimeDuration } from './clock.mjs';
16
17
  import { shuffleArray } from './array.mjs';
17
18
  import { toTitleCase } from './text.mjs';
18
19
  import { toTitleCaseLowerFirst } from './text.mjs';
19
- export { formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst };
20
+ export { arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst };
20
21
  //# sourceMappingURL=index.d.mts.map
@@ -1,7 +1,8 @@
1
+ import arraySortPositions from '../../legacy/libs/arraySortPositions.mjs';
1
2
  import asyncReplace from '../../legacy/libs/replaceAsync.mjs';
2
3
  import { shuffleArray } from './array.mjs';
3
4
  import { formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration } from './clock.mjs';
4
5
  import { countObj, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, objType, } from './objFilter.mjs';
5
6
  import { formatBytes, getAge, getSimplePerc, ruleOfThree } from './simpleMath.mjs';
6
7
  import { addAiMarkerShortcut, toTitleCase, toTitleCaseLowerFirst } from './text.mjs';
7
- export { formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst, };
8
+ export { arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst, };
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var TinyRateLimiter = require('../libs/TinyRateLimiter.cjs');
4
+
5
+
6
+
7
+ exports.TinyRateLimiter = TinyRateLimiter;
@@ -0,0 +1,3 @@
1
+ export { TinyRateLimiter };
2
+ import TinyRateLimiter from '../libs/TinyRateLimiter.mjs';
3
+ //# sourceMappingURL=TinyRateLimiter.d.mts.map
@@ -0,0 +1,2 @@
1
+ import TinyRateLimiter from '../libs/TinyRateLimiter.mjs';
2
+ export { TinyRateLimiter };
package/dist/v1/index.cjs CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  var replaceAsync = require('../legacy/libs/replaceAsync.cjs');
4
4
  var userLevel = require('../legacy/libs/userLevel.cjs');
5
+ var arraySortPositions = require('../legacy/libs/arraySortPositions.cjs');
5
6
  var array = require('./basics/array.cjs');
6
7
  var clock = require('./basics/clock.cjs');
7
8
  var objFilter = require('./basics/objFilter.cjs');
@@ -9,11 +10,13 @@ var simpleMath = require('./basics/simpleMath.cjs');
9
10
  var text = require('./basics/text.cjs');
10
11
  var ColorSafeStringify = require('./libs/ColorSafeStringify.cjs');
11
12
  var TinyPromiseQueue = require('./libs/TinyPromiseQueue.cjs');
13
+ var TinyRateLimiter = require('./libs/TinyRateLimiter.cjs');
12
14
 
13
15
 
14
16
 
15
17
  exports.asyncReplace = replaceAsync;
16
18
  exports.TinyLevelUp = userLevel;
19
+ exports.arraySortPositions = arraySortPositions;
17
20
  exports.shuffleArray = array.shuffleArray;
18
21
  exports.formatCustomTimer = clock.formatCustomTimer;
19
22
  exports.formatDayTimer = clock.formatDayTimer;
@@ -34,3 +37,4 @@ exports.toTitleCase = text.toTitleCase;
34
37
  exports.toTitleCaseLowerFirst = text.toTitleCaseLowerFirst;
35
38
  exports.ColorSafeStringify = ColorSafeStringify;
36
39
  exports.TinyPromiseQueue = TinyPromiseQueue;
40
+ exports.TinyRateLimiter = TinyRateLimiter;
@@ -1,6 +1,8 @@
1
+ import TinyRateLimiter from './libs/TinyRateLimiter.mjs';
1
2
  import ColorSafeStringify from './libs/ColorSafeStringify.mjs';
2
3
  import TinyPromiseQueue from './libs/TinyPromiseQueue.mjs';
3
4
  import TinyLevelUp from '../legacy/libs/userLevel.mjs';
5
+ import arraySortPositions from '../legacy/libs/arraySortPositions.mjs';
4
6
  import { formatBytes } from './basics/simpleMath.mjs';
5
7
  import { addAiMarkerShortcut } from './basics/text.mjs';
6
8
  import { extendObjType } from './basics/objFilter.mjs';
@@ -20,5 +22,5 @@ import { getTimeDuration } from './basics/clock.mjs';
20
22
  import { shuffleArray } from './basics/array.mjs';
21
23
  import { toTitleCase } from './basics/text.mjs';
22
24
  import { toTitleCaseLowerFirst } from './basics/text.mjs';
23
- export { ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst };
25
+ export { TinyRateLimiter, ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst };
24
26
  //# sourceMappingURL=index.d.mts.map
package/dist/v1/index.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  import asyncReplace from '../legacy/libs/replaceAsync.mjs';
2
2
  import TinyLevelUp from '../legacy/libs/userLevel.mjs';
3
+ import arraySortPositions from '../legacy/libs/arraySortPositions.mjs';
3
4
  import { shuffleArray } from './basics/array.mjs';
4
5
  import { formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, } from './basics/clock.mjs';
5
6
  import { countObj, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, objType, checkObj, } from './basics/objFilter.mjs';
@@ -7,4 +8,5 @@ import { formatBytes, getAge, getSimplePerc, ruleOfThree } from './basics/simple
7
8
  import { addAiMarkerShortcut, toTitleCase, toTitleCaseLowerFirst } from './basics/text.mjs';
8
9
  import ColorSafeStringify from './libs/ColorSafeStringify.mjs';
9
10
  import TinyPromiseQueue from './libs/TinyPromiseQueue.mjs';
10
- export { ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst, };
11
+ import TinyRateLimiter from './libs/TinyRateLimiter.mjs';
12
+ export { TinyRateLimiter, ColorSafeStringify, TinyPromiseQueue, TinyLevelUp, arraySortPositions, formatBytes, addAiMarkerShortcut, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst, };
@@ -0,0 +1,196 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Class representing a flexible rate limiter per user.
5
+ *
6
+ * This rate limiter can be configured by maximum number of hits,
7
+ * time interval, or a combination of both. It supports automatic
8
+ * cleanup of inactive users to optimize memory usage.
9
+ *
10
+ * @class
11
+ */
12
+ class TinyRateLimiter {
13
+ /**
14
+ * @param {Object} options
15
+ * @param {number} [options.maxHits] - Max interactions allowed
16
+ * @param {number} [options.interval] - Time window in milliseconds
17
+ * @param {number} [options.cleanupInterval=60000] - Interval for automatic cleanup (ms)
18
+ * @param {number} [options.maxIdle=300000] - Max idle time for a user before being cleaned (ms)
19
+ */
20
+ constructor({ maxHits, interval, cleanupInterval = 60000, maxIdle = 300000 }) {
21
+ /** @param {number|undefined} val */
22
+ const isPositiveInteger = (val) =>
23
+ typeof val === 'number' && Number.isFinite(val) && val >= 1 && Number.isInteger(val);
24
+
25
+ const isMaxHitsValid = isPositiveInteger(maxHits);
26
+ const isIntervalValid = isPositiveInteger(interval);
27
+ const isCleanupValid = isPositiveInteger(cleanupInterval);
28
+ const isMaxIdleValid = isPositiveInteger(maxIdle);
29
+
30
+ if (!isMaxHitsValid && !isIntervalValid)
31
+ throw new Error("RateLimiter requires at least one valid option: 'maxHits' or 'interval'.");
32
+ if (maxHits !== undefined && !isMaxHitsValid)
33
+ throw new Error("'maxHits' must be a positive integer if defined.");
34
+ if (interval !== undefined && !isIntervalValid)
35
+ throw new Error("'interval' must be a positive integer in milliseconds if defined.");
36
+ if (!isCleanupValid)
37
+ throw new Error("'cleanupInterval' must be a positive integer in milliseconds.");
38
+ if (!isMaxIdleValid) throw new Error("'maxIdle' must be a positive integer in milliseconds.");
39
+
40
+ this.maxHits = isMaxHitsValid ? maxHits : null;
41
+ this.interval = isIntervalValid ? interval : null;
42
+ this.cleanupInterval = cleanupInterval;
43
+ this.maxIdle = maxIdle;
44
+
45
+ /** @type {Map<string, number[]>} */
46
+ this.userData = new Map();
47
+
48
+ /** @type {Map<string, number>} */
49
+ this.lastSeen = new Map();
50
+
51
+ // Start automatic cleanup
52
+ this._cleanupTimer = setInterval(() => this._cleanup(), this.cleanupInterval);
53
+ }
54
+
55
+ /**
56
+ * Get the interval window in milliseconds.
57
+ *
58
+ * @returns {number} The interval value.
59
+ * @throws {Error} If interval is not a valid finite number.
60
+ */
61
+ getInterval() {
62
+ if (typeof this.interval !== 'number' || !Number.isFinite(this.interval))
63
+ throw new Error("'interval' is not a valid finite number.");
64
+ return this.interval;
65
+ }
66
+
67
+ /**
68
+ * Get the maximum number of allowed hits.
69
+ *
70
+ * @returns {number} The maxHits value.
71
+ * @throws {Error} If maxHits is not a valid finite number.
72
+ */
73
+ getMaxHits() {
74
+ if (typeof this.maxHits !== 'number' || !Number.isFinite(this.maxHits)) {
75
+ throw new Error("'maxHits' is not a valid finite number.");
76
+ }
77
+ return this.maxHits;
78
+ }
79
+
80
+ /**
81
+ * Register a hit for a specific user
82
+ * @param {string} userId
83
+ */
84
+ hit(userId) {
85
+ const now = Date.now();
86
+
87
+ if (!this.userData.has(userId)) {
88
+ this.userData.set(userId, []);
89
+ }
90
+
91
+ const history = this.userData.get(userId);
92
+ if (!history) throw new Error(`No data found for userId: ${userId}`);
93
+
94
+ history.push(now);
95
+ this.lastSeen.set(userId, now);
96
+
97
+ // Clean up old entries
98
+ if (this.interval !== null) {
99
+ const interval = this.getInterval();
100
+ const cutoff = now - interval;
101
+ while (history.length && history[0] < cutoff) {
102
+ history.shift();
103
+ }
104
+ }
105
+
106
+ // Optional: keep only the last N entries for memory optimization
107
+ if (this.maxHits !== null) {
108
+ const maxHits = this.getMaxHits();
109
+ if (history.length > maxHits) {
110
+ history.splice(0, history.length - maxHits);
111
+ }
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Check if the user is currently rate limited
117
+ * @param {string} userId
118
+ * @returns {boolean}
119
+ */
120
+ isRateLimited(userId) {
121
+ const now = Date.now();
122
+
123
+ if (!this.userData.has(userId)) return false;
124
+
125
+ const history = this.userData.get(userId);
126
+ if (!history) throw new Error(`No data found for userId: ${userId}`);
127
+
128
+ if (this.interval !== null) {
129
+ const interval = this.getInterval();
130
+ const recent = history.filter((t) => t > now - interval);
131
+ if (this.maxHits !== null) {
132
+ return recent.length >= this.getMaxHits();
133
+ }
134
+ return recent.length > 0;
135
+ }
136
+
137
+ if (this.maxHits !== null) {
138
+ return history.length >= this.getMaxHits();
139
+ }
140
+
141
+ return false;
142
+ }
143
+
144
+ /**
145
+ * Manually reset user data
146
+ * @param {string} userId
147
+ */
148
+ reset(userId) {
149
+ this.userData.delete(userId);
150
+ this.lastSeen.delete(userId);
151
+ }
152
+
153
+ /**
154
+ * Set hit timestamps for a user
155
+ * @param {string} userId
156
+ * @param {number[]} timestamps
157
+ */
158
+ setData(userId, timestamps) {
159
+ this.userData.set(userId, timestamps);
160
+ this.lastSeen.set(userId, Date.now());
161
+ }
162
+
163
+ /**
164
+ * Get timestamps from user
165
+ * @param {string} userId
166
+ * @returns {number[]}
167
+ */
168
+ getData(userId) {
169
+ return this.userData.get(userId) || [];
170
+ }
171
+
172
+ /**
173
+ * Cleanup old/inactive users
174
+ * @private
175
+ */
176
+ _cleanup() {
177
+ const now = Date.now();
178
+ for (const [userId, last] of this.lastSeen.entries()) {
179
+ if (now - last > this.maxIdle) {
180
+ this.userData.delete(userId);
181
+ this.lastSeen.delete(userId);
182
+ }
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Destroy the rate limiter, stopping all intervals
188
+ */
189
+ destroy() {
190
+ clearInterval(this._cleanupTimer);
191
+ this.userData.clear();
192
+ this.lastSeen.clear();
193
+ }
194
+ }
195
+
196
+ module.exports = TinyRateLimiter;