tiny-essentials 1.9.1 → 1.10.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.
- package/dist/TinyBasicsEs.js +155 -98
- package/dist/TinyBasicsEs.min.js +1 -1
- package/dist/TinyEssentials.js +605 -174
- package/dist/TinyEssentials.min.js +1 -1
- package/dist/TinyRateLimiter.js +450 -76
- package/dist/TinyRateLimiter.min.js +1 -1
- package/dist/legacy/firebase/mySQL.cjs +1 -1
- package/dist/v1/basics/objFilter.cjs +155 -98
- package/dist/v1/basics/objFilter.d.mts +16 -26
- package/dist/v1/basics/objFilter.mjs +146 -77
- package/dist/v1/libs/TinyRateLimiter.cjs +450 -76
- package/dist/v1/libs/TinyRateLimiter.d.mts +186 -31
- package/dist/v1/libs/TinyRateLimiter.mjs +420 -75
- package/docs/basics/objFilter.md +7 -0
- package/docs/libs/TinyRateLimiter.md +167 -15
- package/package.json +1 -1
|
@@ -1,86 +1,241 @@
|
|
|
1
1
|
export default TinyRateLimiter;
|
|
2
|
+
export type OnMemoryExceeded = (groupId: string) => void;
|
|
3
|
+
export type OnGroupExpired = (groupId: string) => void;
|
|
4
|
+
/** @typedef {(groupId: string) => void} OnMemoryExceeded */
|
|
5
|
+
/** @typedef {(groupId: string) => void} OnGroupExpired */
|
|
2
6
|
/**
|
|
3
|
-
* Class representing a flexible rate limiter per user.
|
|
7
|
+
* Class representing a flexible rate limiter per user or group.
|
|
4
8
|
*
|
|
5
|
-
* This rate limiter
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* @class
|
|
9
|
+
* This rate limiter supports limiting per user or per group by mapping
|
|
10
|
+
* userIds to a common groupId. All users within the same group share
|
|
11
|
+
* rate limits.
|
|
10
12
|
*/
|
|
11
13
|
declare class TinyRateLimiter {
|
|
12
14
|
/**
|
|
13
15
|
* @param {Object} options
|
|
16
|
+
* @param {number|null} [options.maxMemory] - Max memory allowed
|
|
14
17
|
* @param {number} [options.maxHits] - Max interactions allowed
|
|
15
18
|
* @param {number} [options.interval] - Time window in milliseconds
|
|
16
19
|
* @param {number} [options.cleanupInterval] - Interval for automatic cleanup (ms)
|
|
17
20
|
* @param {number} [options.maxIdle=300000] - Max idle time for a user before being cleaned (ms)
|
|
18
21
|
*/
|
|
19
|
-
constructor({ maxHits, interval, cleanupInterval, maxIdle }: {
|
|
22
|
+
constructor({ maxHits, interval, cleanupInterval, maxIdle, maxMemory }: {
|
|
23
|
+
maxMemory?: number | null | undefined;
|
|
20
24
|
maxHits?: number | undefined;
|
|
21
25
|
interval?: number | undefined;
|
|
22
26
|
cleanupInterval?: number | undefined;
|
|
23
27
|
maxIdle?: number | undefined;
|
|
24
28
|
});
|
|
25
|
-
maxHits: number | null | undefined;
|
|
26
|
-
interval: number | null | undefined;
|
|
27
|
-
cleanupInterval: number | null | undefined;
|
|
28
|
-
maxIdle: number;
|
|
29
29
|
/** @type {Map<string, number[]>} */
|
|
30
|
-
|
|
30
|
+
groupData: Map<string, number[]>;
|
|
31
31
|
/** @type {Map<string, number>} */
|
|
32
32
|
lastSeen: Map<string, number>;
|
|
33
|
-
|
|
33
|
+
/** @type {Map<string, string>} */
|
|
34
|
+
userToGroup: Map<string, string>;
|
|
35
|
+
/** @type {Map<string, boolean>} */
|
|
36
|
+
groupFlags: Map<string, boolean>;
|
|
34
37
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* @returns {number} The interval value.
|
|
38
|
-
* @throws {Error} If interval is not a valid finite number.
|
|
38
|
+
* @type {Map<string, number>}
|
|
39
|
+
* Stores TTL (in ms) for each groupId individually
|
|
39
40
|
*/
|
|
40
|
-
|
|
41
|
+
groupTTL: Map<string, number>;
|
|
41
42
|
/**
|
|
42
|
-
*
|
|
43
|
+
* Set the callback to be triggered when a group exceeds its limit
|
|
44
|
+
* @param {OnMemoryExceeded} callback
|
|
45
|
+
*/
|
|
46
|
+
setOnMemoryExceeded(callback: OnMemoryExceeded): void;
|
|
47
|
+
/**
|
|
48
|
+
* Clear the onMemoryExceeded callback
|
|
49
|
+
*/
|
|
50
|
+
clearOnMemoryExceeded(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Set the callback to be triggered when a group expires and is removed.
|
|
43
53
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
54
|
+
* This callback is called automatically during cleanup when a group
|
|
55
|
+
* becomes inactive for longer than its TTL.
|
|
56
|
+
*
|
|
57
|
+
* @param {OnGroupExpired} callback - A function that receives the expired groupId.
|
|
46
58
|
*/
|
|
47
|
-
|
|
59
|
+
setOnGroupExpired(callback: OnGroupExpired): void;
|
|
60
|
+
/**
|
|
61
|
+
* Clear the onGroupExpired callback
|
|
62
|
+
*/
|
|
63
|
+
clearOnGroupExpired(): void;
|
|
64
|
+
/**
|
|
65
|
+
* Check if a given ID is a groupId (not a userId)
|
|
66
|
+
* @param {string} id
|
|
67
|
+
* @returns {boolean}
|
|
68
|
+
*/
|
|
69
|
+
isGroupId(id: string): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Get all user IDs that belong to a given group.
|
|
72
|
+
* @param {string} groupId
|
|
73
|
+
* @returns {string[]}
|
|
74
|
+
*/
|
|
75
|
+
getUsersInGroup(groupId: string): string[];
|
|
76
|
+
/**
|
|
77
|
+
* Set TTL (in milliseconds) for a specific group
|
|
78
|
+
* @param {string} groupId
|
|
79
|
+
* @param {number} ttl
|
|
80
|
+
*/
|
|
81
|
+
setGroupTTL(groupId: string, ttl: number): void;
|
|
82
|
+
/**
|
|
83
|
+
* Get TTL (in ms) for a specific group.
|
|
84
|
+
* @param {string} groupId
|
|
85
|
+
* @returns {number|null}
|
|
86
|
+
*/
|
|
87
|
+
getGroupTTL(groupId: string): number | null;
|
|
88
|
+
/**
|
|
89
|
+
* Delete the TTL setting for a specific group
|
|
90
|
+
* @param {string} groupId
|
|
91
|
+
*/
|
|
92
|
+
deleteGroupTTL(groupId: string): void;
|
|
93
|
+
/**
|
|
94
|
+
* Assign a userId to a groupId, with merge if user has existing data.
|
|
95
|
+
* @param {string} userId
|
|
96
|
+
* @param {string} groupId
|
|
97
|
+
* @throws {Error} If userId is already assigned to a different group
|
|
98
|
+
*/
|
|
99
|
+
assignToGroup(userId: string, groupId: string): void;
|
|
100
|
+
/**
|
|
101
|
+
* Get the groupId for a given userId
|
|
102
|
+
* @param {string} userId
|
|
103
|
+
* @returns {string}
|
|
104
|
+
*/
|
|
105
|
+
getGroupId(userId: string): string;
|
|
48
106
|
/**
|
|
49
107
|
* Register a hit for a specific user
|
|
50
108
|
* @param {string} userId
|
|
51
109
|
*/
|
|
52
110
|
hit(userId: string): void;
|
|
53
111
|
/**
|
|
54
|
-
* Check if the user is currently rate limited
|
|
112
|
+
* Check if the user (via their group) is currently rate limited
|
|
55
113
|
* @param {string} userId
|
|
56
114
|
* @returns {boolean}
|
|
57
115
|
*/
|
|
58
116
|
isRateLimited(userId: string): boolean;
|
|
59
117
|
/**
|
|
60
|
-
* Manually reset
|
|
118
|
+
* Manually reset group data
|
|
119
|
+
* @param {string} groupId
|
|
120
|
+
*/
|
|
121
|
+
resetGroup(groupId: string): void;
|
|
122
|
+
/**
|
|
123
|
+
* Manually reset user data.
|
|
124
|
+
*
|
|
125
|
+
* @deprecated Use `resetUserGroup(userId)` instead. This method will be removed in future versions.
|
|
61
126
|
* @param {string} userId
|
|
127
|
+
* @returns {void}
|
|
62
128
|
*/
|
|
63
129
|
reset(userId: string): void;
|
|
64
130
|
/**
|
|
65
|
-
*
|
|
131
|
+
* Manually reset a user mapping
|
|
66
132
|
* @param {string} userId
|
|
133
|
+
*/
|
|
134
|
+
resetUserGroup(userId: string): void;
|
|
135
|
+
/**
|
|
136
|
+
* Set custom timestamps to a group
|
|
137
|
+
* @param {string} groupId
|
|
67
138
|
* @param {number[]} timestamps
|
|
68
139
|
*/
|
|
69
|
-
setData(
|
|
140
|
+
setData(groupId: string, timestamps: number[]): void;
|
|
70
141
|
/**
|
|
71
|
-
*
|
|
72
|
-
* @param {string}
|
|
142
|
+
* Check if a group has data
|
|
143
|
+
* @param {string} groupId
|
|
144
|
+
* @returns {boolean}
|
|
145
|
+
*/
|
|
146
|
+
hasData(groupId: string): boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Get timestamps from a group
|
|
149
|
+
* @param {string} groupId
|
|
73
150
|
* @returns {number[]}
|
|
74
151
|
*/
|
|
75
|
-
getData(
|
|
152
|
+
getData(groupId: string): number[];
|
|
153
|
+
/**
|
|
154
|
+
* Get the maximum idle time (in milliseconds) before a group is considered expired.
|
|
155
|
+
* @returns {number}
|
|
156
|
+
*/
|
|
157
|
+
getMaxIdle(): number;
|
|
158
|
+
/**
|
|
159
|
+
* Set the maximum idle time (in milliseconds) before a group is considered expired.
|
|
160
|
+
* @param {number} ms
|
|
161
|
+
*/
|
|
162
|
+
setMaxIdle(ms: number): void;
|
|
76
163
|
/**
|
|
77
|
-
* Cleanup old/inactive
|
|
164
|
+
* Cleanup old/inactive groups with individual TTLs
|
|
78
165
|
* @private
|
|
79
166
|
*/
|
|
80
167
|
private _cleanup;
|
|
81
168
|
/**
|
|
82
|
-
*
|
|
169
|
+
* Get list of active group IDs
|
|
170
|
+
* @returns {string[]}
|
|
171
|
+
*/
|
|
172
|
+
getActiveGroups(): string[];
|
|
173
|
+
/**
|
|
174
|
+
* Get a shallow copy of all user-to-group mappings as a plain object
|
|
175
|
+
* @returns {Record<string, string>}
|
|
176
|
+
*/
|
|
177
|
+
getAllUserMappings(): Record<string, string>;
|
|
178
|
+
/**
|
|
179
|
+
* Get the interval window in milliseconds.
|
|
180
|
+
* @returns {number}
|
|
181
|
+
*/
|
|
182
|
+
getInterval(): number;
|
|
183
|
+
/**
|
|
184
|
+
* Get the maximum number of allowed hits.
|
|
185
|
+
* @returns {number}
|
|
186
|
+
*/
|
|
187
|
+
getMaxHits(): number;
|
|
188
|
+
/**
|
|
189
|
+
* Get the total number of hits recorded for a group.
|
|
190
|
+
* @param {string} groupId
|
|
191
|
+
* @returns {number}
|
|
192
|
+
*/
|
|
193
|
+
getTotalHits(groupId: string): number;
|
|
194
|
+
/**
|
|
195
|
+
* Get the timestamp of the last hit for a group.
|
|
196
|
+
* @param {string} groupId
|
|
197
|
+
* @returns {number|null}
|
|
198
|
+
*/
|
|
199
|
+
getLastHit(groupId: string): number | null;
|
|
200
|
+
/**
|
|
201
|
+
* Get milliseconds since the last hit for a group.
|
|
202
|
+
* @param {string} groupId
|
|
203
|
+
* @returns {number|null}
|
|
204
|
+
*/
|
|
205
|
+
getTimeSinceLastHit(groupId: string): number | null;
|
|
206
|
+
/**
|
|
207
|
+
* Internal utility to compute average spacing
|
|
208
|
+
* @private
|
|
209
|
+
* @param {number[]|undefined} history
|
|
210
|
+
* @returns {number|null}
|
|
211
|
+
*/
|
|
212
|
+
private _calculateAverageSpacing;
|
|
213
|
+
/**
|
|
214
|
+
* Get average time between hits for a group (ms).
|
|
215
|
+
* @param {string} groupId
|
|
216
|
+
* @returns {number|null}
|
|
217
|
+
*/
|
|
218
|
+
getAverageHitSpacing(groupId: string): number | null;
|
|
219
|
+
/**
|
|
220
|
+
* Get metrics about a group's activity.
|
|
221
|
+
* @param {string} groupId
|
|
222
|
+
* @returns {{
|
|
223
|
+
* totalHits: number,
|
|
224
|
+
* lastHit: number|null,
|
|
225
|
+
* timeSinceLastHit: number|null,
|
|
226
|
+
* averageHitSpacing: number|null
|
|
227
|
+
* }}
|
|
228
|
+
*/
|
|
229
|
+
getMetrics(groupId: string): {
|
|
230
|
+
totalHits: number;
|
|
231
|
+
lastHit: number | null;
|
|
232
|
+
timeSinceLastHit: number | null;
|
|
233
|
+
averageHitSpacing: number | null;
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
* Destroy the rate limiter, stopping cleanup and clearing data
|
|
83
237
|
*/
|
|
84
238
|
destroy(): void;
|
|
239
|
+
#private;
|
|
85
240
|
}
|
|
86
241
|
//# sourceMappingURL=TinyRateLimiter.d.mts.map
|