tiny-essentials 1.3.2 → 1.5.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 +45 -22
- package/dist/TinyBasicsEs.min.js +1 -1
- package/dist/TinyEssentials.js +223 -22
- package/dist/TinyEssentials.min.js +1 -1
- package/dist/TinyPromiseQueue.js +214 -0
- package/dist/TinyPromiseQueue.min.js +1 -0
- package/dist/legacy/crypto/decrypt.d.mts +1 -0
- package/dist/legacy/crypto/default.d.mts +1 -0
- package/dist/legacy/crypto/encrypt.d.mts +1 -0
- package/dist/legacy/crypto/index.d.mts +1 -0
- package/dist/legacy/firebase/cookieSession.d.mts +1 -0
- package/dist/legacy/firebase/database/index.d.mts +1 -0
- package/dist/legacy/firebase/database/presence.d.mts +1 -0
- package/dist/legacy/firebase/database/saveAsync.d.mts +1 -0
- package/dist/legacy/firebase/databaseEscape.d.mts +1 -0
- package/dist/legacy/firebase/databaseLogger.d.mts +1 -0
- package/dist/legacy/firebase/discord/api/addGuildMember.d.mts +1 -0
- package/dist/legacy/firebase/discord/api/getGuildWidget.d.mts +1 -0
- package/dist/legacy/firebase/discord/api/getToken.d.mts +1 -0
- package/dist/legacy/firebase/discord/api/getUser.d.mts +1 -0
- package/dist/legacy/firebase/discord/api/getUserConnections.d.mts +1 -0
- package/dist/legacy/firebase/discord/api/getUserGuilds.d.mts +1 -0
- package/dist/legacy/firebase/discord/api/index.d.mts +1 -0
- package/dist/legacy/firebase/discord/api/refreshToken.d.mts +1 -0
- package/dist/legacy/firebase/discord/api/revokeToken.d.mts +1 -0
- package/dist/legacy/firebase/discord/config.d.mts +1 -0
- package/dist/legacy/firebase/discord/firebase_redirect/index.d.mts +1 -0
- package/dist/legacy/firebase/discord/firebase_redirect/login.d.mts +1 -0
- package/dist/legacy/firebase/discord/firebase_redirect/logout.d.mts +1 -0
- package/dist/legacy/firebase/discord/get/authURLGenerator.d.mts +1 -0
- package/dist/legacy/firebase/discord/get/cookie-session.d.mts +1 -0
- package/dist/legacy/firebase/discord/get/credentials.d.mts +1 -0
- package/dist/legacy/firebase/discord/get/errorValidator.d.mts +1 -0
- package/dist/legacy/firebase/discord/get/index.d.mts +1 -0
- package/dist/legacy/firebase/discord/get/randomAvatar.d.mts +1 -0
- package/dist/legacy/firebase/discord/http/index.d.mts +1 -0
- package/dist/legacy/firebase/discord/http/login.d.mts +1 -0
- package/dist/legacy/firebase/discord/http/logout.d.mts +1 -0
- package/dist/legacy/firebase/discord/http/redirect.d.mts +1 -0
- package/dist/legacy/firebase/discord/http/refreshToken.d.mts +1 -0
- package/dist/legacy/firebase/discord/index.d.mts +1 -0
- package/dist/legacy/firebase/discord/template/cookie-session.d.mts +1 -0
- package/dist/legacy/firebase/domainRedirect.d.mts +1 -0
- package/dist/legacy/firebase/escape.d.mts +1 -0
- package/dist/legacy/firebase/getDBAsync.d.mts +1 -0
- package/dist/legacy/firebase/getDBData.d.mts +1 -0
- package/dist/legacy/firebase/getDBValue.d.mts +1 -0
- package/dist/legacy/firebase/index.d.mts +1 -0
- package/dist/legacy/firebase/isEmulator.d.mts +1 -0
- package/dist/legacy/firebase/logger.d.mts +1 -0
- package/dist/legacy/firebase/mySQL.d.mts +1 -0
- package/dist/legacy/firebase/mysqlConnector/create.d.mts +1 -0
- package/dist/legacy/firebase/mysqlConnector/index.d.mts +1 -0
- package/dist/legacy/firebase/mysqlConnector/nextPrev.d.mts +1 -0
- package/dist/legacy/firebase/mysqlConnector/pagination.d.mts +1 -0
- package/dist/legacy/firebase/mysqlConnector/sameUser.d.mts +1 -0
- package/dist/legacy/firebase/transactionDBAsync.d.mts +1 -0
- package/dist/legacy/get/countObj.d.mts +1 -0
- package/dist/legacy/get/decimalColor.d.mts +1 -0
- package/dist/legacy/get/objType.d.mts +1 -0
- package/dist/legacy/get/pagination.d.mts +1 -0
- package/dist/legacy/get/queryUrlByName.d.mts +1 -0
- package/dist/legacy/get/queryUrlJSON.d.mts +1 -0
- package/dist/legacy/get/super_string_filter.d.mts +1 -0
- package/dist/legacy/get/versionCheck.d.mts +1 -0
- package/dist/legacy/http/HTTP-1.0.d.mts +1 -0
- package/dist/legacy/http/auth.d.mts +1 -0
- package/dist/legacy/http/check_domain.d.mts +1 -0
- package/dist/legacy/http/csrfTokenAnalyze.d.mts +1 -0
- package/dist/legacy/http/domainValidator.d.mts +1 -0
- package/dist/legacy/http/errorsCallback.d.mts +1 -0
- package/dist/legacy/http/fetch/json.d.mts +1 -0
- package/dist/legacy/http/fetch/text.d.mts +1 -0
- package/dist/legacy/http/fileCache.d.mts +1 -0
- package/dist/legacy/http/getDomainURL.d.mts +1 -0
- package/dist/legacy/http/userIP.d.mts +1 -0
- package/dist/legacy/index.d.mts +1 -0
- package/dist/legacy/libs/arraySortPositions.d.mts +1 -0
- package/dist/legacy/libs/capitalize.d.mts +1 -0
- package/dist/legacy/libs/convertBytes.d.mts +1 -0
- package/dist/legacy/libs/custom_module_loader.d.mts +1 -0
- package/dist/legacy/libs/dice.d.mts +1 -0
- package/dist/legacy/libs/markdown.d.mts +1 -0
- package/dist/legacy/libs/percentage.d.mts +1 -0
- package/dist/legacy/libs/regex/getLetter.d.mts +1 -0
- package/dist/legacy/libs/replaceAsync.d.mts +1 -0
- package/dist/legacy/libs/rule3.d.mts +1 -0
- package/dist/legacy/libs/userLevel.d.mts +1 -0
- package/dist/legacy/momentjs/getAge.d.mts +1 -0
- package/dist/legacy/momentjs/index.d.mts +1 -0
- package/dist/legacy/momentjs/timeDuration.d.mts +1 -0
- package/dist/legacy/socket.io/antiFlood/index.d.mts +1 -0
- package/dist/legacy/socket.io/antiFlood/install.d.mts +1 -0
- package/dist/legacy/socket.io/antiFlood/verify.d.mts +1 -0
- package/dist/legacy/socket.io/cookie-session.d.mts +1 -0
- package/dist/legacy/socket.io/discord.d.mts +1 -0
- package/dist/legacy/socket.io/index.d.mts +1 -0
- package/dist/v1/basics/array.d.mts +1 -0
- package/dist/v1/basics/clock.d.mts +1 -0
- package/dist/v1/basics/index.d.mts +1 -0
- package/dist/v1/basics/objFilter.cjs +46 -22
- package/dist/v1/basics/objFilter.d.mts +13 -2
- package/dist/v1/basics/objFilter.mjs +43 -22
- package/dist/v1/basics/simpleMath.d.mts +1 -0
- package/dist/v1/basics/text.d.mts +1 -0
- package/dist/v1/build/TinyLevelUp.d.mts +1 -0
- package/dist/v1/build/TinyPromiseQueue.cjs +7 -0
- package/dist/v1/build/TinyPromiseQueue.d.mts +3 -0
- package/dist/v1/build/TinyPromiseQueue.mjs +2 -0
- package/dist/v1/index.cjs +3 -0
- package/dist/v1/index.d.mts +4 -1
- package/dist/v1/index.mjs +3 -2
- package/dist/v1/libs/TinyPromiseQueue.cjs +175 -0
- package/dist/v1/libs/TinyPromiseQueue.d.mts +63 -0
- package/dist/v1/libs/TinyPromiseQueue.mjs +159 -0
- package/docs/README.md +5 -0
- package/docs/basics/asyncReplace.md +39 -0
- package/docs/basics/objFilter.md +33 -0
- package/docs/libs/TinyLevelUp.md +108 -0
- package/docs/libs/TinyPromiseQueue.md +126 -0
- package/package.json +4 -2
|
@@ -19,45 +19,45 @@ import { Buffer } from 'buffer';
|
|
|
19
19
|
*/
|
|
20
20
|
const typeValidator = {
|
|
21
21
|
items: {
|
|
22
|
-
/**
|
|
22
|
+
/** @param {*} val @returns {val is undefined} */
|
|
23
23
|
undefined: (val) => typeof val === 'undefined',
|
|
24
|
-
/**
|
|
24
|
+
/** @param {*} val @returns {val is null} */
|
|
25
25
|
null: (val) => val === null,
|
|
26
|
-
/**
|
|
26
|
+
/** @param {*} val @returns {val is boolean} */
|
|
27
27
|
boolean: (val) => typeof val === 'boolean',
|
|
28
|
-
/**
|
|
28
|
+
/** @param {*} val @returns {val is number} */
|
|
29
29
|
number: (val) => typeof val === 'number' && !isNaN(val),
|
|
30
|
-
/**
|
|
30
|
+
/** @param {*} val @returns {val is bigint} */
|
|
31
31
|
bigint: (val) => typeof val === 'bigint',
|
|
32
|
-
/**
|
|
32
|
+
/** @param {*} val @returns {val is string} */
|
|
33
33
|
string: (val) => typeof val === 'string',
|
|
34
|
-
/**
|
|
34
|
+
/** @param {*} val @returns {val is symbol} */
|
|
35
35
|
symbol: (val) => typeof val === 'symbol',
|
|
36
|
-
/**
|
|
36
|
+
/** @param {*} val @returns {val is Function} */
|
|
37
37
|
function: (val) => typeof val === 'function',
|
|
38
|
-
/**
|
|
38
|
+
/** @param {*} val @returns {val is Array<any>} */
|
|
39
39
|
array: (val) => Array.isArray(val),
|
|
40
|
-
/**
|
|
40
|
+
/** @param {*} val @returns {val is Date} */
|
|
41
41
|
date: (val) => val instanceof Date,
|
|
42
|
-
/**
|
|
42
|
+
/** @param {*} val @returns {val is RegExp} */
|
|
43
43
|
regexp: (val) => val instanceof RegExp,
|
|
44
|
-
/**
|
|
44
|
+
/** @param {*} val @returns {val is Map<any, any>} */
|
|
45
45
|
map: (val) => val instanceof Map,
|
|
46
|
-
/**
|
|
46
|
+
/** @param {*} val @returns {val is Set<any>} */
|
|
47
47
|
set: (val) => val instanceof Set,
|
|
48
|
-
/**
|
|
48
|
+
/** @param {*} val @returns {val is WeakMap<object, any>} */
|
|
49
49
|
weakmap: (val) => val instanceof WeakMap,
|
|
50
|
-
/**
|
|
50
|
+
/** @param {*} val @returns {val is WeakSet<object>} */
|
|
51
51
|
weakset: (val) => val instanceof WeakSet,
|
|
52
|
-
/**
|
|
52
|
+
/** @param {*} val @returns {val is Promise<any>} */
|
|
53
53
|
promise: (val) => val instanceof Promise,
|
|
54
|
-
/**
|
|
54
|
+
/** @param {*} val @returns {val is Buffer} */
|
|
55
55
|
buffer: (val) => typeof Buffer !== 'undefined' && Buffer.isBuffer(val),
|
|
56
|
-
/**
|
|
56
|
+
/** @param {*} val @returns {val is File} */
|
|
57
57
|
file: (val) => typeof File !== 'undefined' && val instanceof File,
|
|
58
|
-
/**
|
|
58
|
+
/** @param {*} val @returns {val is HTMLElement} */
|
|
59
59
|
htmlelement: (val) => typeof HTMLElement !== 'undefined' && val instanceof HTMLElement,
|
|
60
|
-
/**
|
|
60
|
+
/** @param {*} val @returns {val is object} */
|
|
61
61
|
object: (val) => typeof val === 'object' && val !== null,
|
|
62
62
|
},
|
|
63
63
|
/** Evaluation order of the type checkers. */
|
|
@@ -172,7 +172,7 @@ const getType = (val) => {
|
|
|
172
172
|
if (val === null)
|
|
173
173
|
return 'null';
|
|
174
174
|
for (const name of typeValidator.order)
|
|
175
|
-
if (
|
|
175
|
+
if (typeof typeValidator.items[name] !== 'function' || typeValidator.items[name](val))
|
|
176
176
|
return name;
|
|
177
177
|
return 'unknown';
|
|
178
178
|
};
|
|
@@ -198,10 +198,31 @@ export function objType(obj, type) {
|
|
|
198
198
|
return result === type.toLowerCase();
|
|
199
199
|
return result;
|
|
200
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Checks the type of a given object and returns the validation value if a known type is detected.
|
|
203
|
+
*
|
|
204
|
+
* @param {*} obj - The object to check or identify.
|
|
205
|
+
* @returns {{ valid:*; type: string | null }} - Returns the type result.
|
|
206
|
+
*/
|
|
207
|
+
export function checkObj(obj) {
|
|
208
|
+
/** @type {{ valid:*; type: string | null }} */
|
|
209
|
+
const data = { valid: null, type: null };
|
|
210
|
+
for (const name of typeValidator.order) {
|
|
211
|
+
if (typeof typeValidator.items[name] === 'function') {
|
|
212
|
+
const result = typeValidator.items[name](obj);
|
|
213
|
+
if (result) {
|
|
214
|
+
data.valid = result;
|
|
215
|
+
data.type = name;
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return data;
|
|
221
|
+
}
|
|
201
222
|
/**
|
|
202
223
|
* Counts the number of elements in an array or the number of properties in an object.
|
|
203
224
|
*
|
|
204
|
-
* @param {
|
|
225
|
+
* @param {Array<*>|Record<string|number, any>} obj - The array or object to count.
|
|
205
226
|
* @returns {number} - The count of items (array elements or object keys), or `0` if the input is neither an array nor an object.
|
|
206
227
|
*
|
|
207
228
|
* @example
|
|
@@ -52,3 +52,4 @@ export function getSimplePerc(price: number, percentage: number): number;
|
|
|
52
52
|
* @returns {number|null} The age in years, or null if `timeData` is not provided or invalid.
|
|
53
53
|
*/
|
|
54
54
|
export function getAge(timeData?: number | string | Date, now?: Date | null): number | null;
|
|
55
|
+
//# sourceMappingURL=simpleMath.d.mts.map
|
package/dist/v1/index.cjs
CHANGED
|
@@ -7,6 +7,7 @@ var clock = require('./basics/clock.cjs');
|
|
|
7
7
|
var objFilter = require('./basics/objFilter.cjs');
|
|
8
8
|
var simpleMath = require('./basics/simpleMath.cjs');
|
|
9
9
|
var text = require('./basics/text.cjs');
|
|
10
|
+
var TinyPromiseQueue = require('./libs/TinyPromiseQueue.cjs');
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
|
|
@@ -17,6 +18,7 @@ exports.formatCustomTimer = clock.formatCustomTimer;
|
|
|
17
18
|
exports.formatDayTimer = clock.formatDayTimer;
|
|
18
19
|
exports.formatTimer = clock.formatTimer;
|
|
19
20
|
exports.getTimeDuration = clock.getTimeDuration;
|
|
21
|
+
exports.checkObj = objFilter.checkObj;
|
|
20
22
|
exports.cloneObjTypeOrder = objFilter.cloneObjTypeOrder;
|
|
21
23
|
exports.countObj = objFilter.countObj;
|
|
22
24
|
exports.extendObjType = objFilter.extendObjType;
|
|
@@ -27,3 +29,4 @@ exports.getSimplePerc = simpleMath.getSimplePerc;
|
|
|
27
29
|
exports.ruleOfThree = simpleMath.ruleOfThree;
|
|
28
30
|
exports.toTitleCase = text.toTitleCase;
|
|
29
31
|
exports.toTitleCaseLowerFirst = text.toTitleCaseLowerFirst;
|
|
32
|
+
exports.TinyPromiseQueue = TinyPromiseQueue;
|
package/dist/v1/index.d.mts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import TinyPromiseQueue from './libs/TinyPromiseQueue.mjs';
|
|
1
2
|
import TinyLevelUp from '../legacy/libs/userLevel.mjs';
|
|
2
3
|
import { extendObjType } from './basics/objFilter.mjs';
|
|
3
4
|
import { reorderObjTypeOrder } from './basics/objFilter.mjs';
|
|
4
5
|
import { cloneObjTypeOrder } from './basics/objFilter.mjs';
|
|
5
6
|
import { countObj } from './basics/objFilter.mjs';
|
|
7
|
+
import { checkObj } from './basics/objFilter.mjs';
|
|
6
8
|
import { objType } from './basics/objFilter.mjs';
|
|
7
9
|
import { ruleOfThree } from './basics/simpleMath.mjs';
|
|
8
10
|
import { getSimplePerc } from './basics/simpleMath.mjs';
|
|
@@ -15,4 +17,5 @@ import { getTimeDuration } from './basics/clock.mjs';
|
|
|
15
17
|
import { shuffleArray } from './basics/array.mjs';
|
|
16
18
|
import { toTitleCase } from './basics/text.mjs';
|
|
17
19
|
import { toTitleCaseLowerFirst } from './basics/text.mjs';
|
|
18
|
-
export { TinyLevelUp, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst };
|
|
20
|
+
export { TinyPromiseQueue, TinyLevelUp, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst };
|
|
21
|
+
//# sourceMappingURL=index.d.mts.map
|
package/dist/v1/index.mjs
CHANGED
|
@@ -2,7 +2,8 @@ import asyncReplace from '../legacy/libs/replaceAsync.mjs';
|
|
|
2
2
|
import TinyLevelUp from '../legacy/libs/userLevel.mjs';
|
|
3
3
|
import { shuffleArray } from './basics/array.mjs';
|
|
4
4
|
import { formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, } from './basics/clock.mjs';
|
|
5
|
-
import { countObj, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, objType, } from './basics/objFilter.mjs';
|
|
5
|
+
import { countObj, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, objType, checkObj, } from './basics/objFilter.mjs';
|
|
6
6
|
import { getAge, getSimplePerc, ruleOfThree } from './basics/simpleMath.mjs';
|
|
7
7
|
import { toTitleCase, toTitleCaseLowerFirst } from './basics/text.mjs';
|
|
8
|
-
|
|
8
|
+
import TinyPromiseQueue from './libs/TinyPromiseQueue.mjs';
|
|
9
|
+
export { TinyPromiseQueue, TinyLevelUp, extendObjType, reorderObjTypeOrder, cloneObjTypeOrder, countObj, checkObj, objType, ruleOfThree, getSimplePerc, asyncReplace, getAge, formatCustomTimer, formatDayTimer, formatTimer, getTimeDuration, shuffleArray, toTitleCase, toTitleCaseLowerFirst, };
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A queue system for managing and executing asynchronous tasks sequentially, one at a time.
|
|
5
|
+
*
|
|
6
|
+
* Tasks can be delayed, reordered, canceled, and processed in strict order. The queue ensures that each task
|
|
7
|
+
* is executed after the previous one finishes, and any task can be skipped or canceled if needed.
|
|
8
|
+
*
|
|
9
|
+
* @class
|
|
10
|
+
*/
|
|
11
|
+
class TinyPromiseQueue {
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {Object} QueuedTask
|
|
14
|
+
* @property {() => Promise<any>} task - The async task to execute.
|
|
15
|
+
* @property {(value: any) => any} resolve - The resolve function from the Promise.
|
|
16
|
+
* @property {(reason?: any) => any} reject - The reject function from the Promise.
|
|
17
|
+
* @property {string|undefined} [id] - Optional identifier for the task.
|
|
18
|
+
* @property {number|null|undefined} [delay] - Optional delay (in ms) before the task is executed.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/** @type {Array<QueuedTask>} */
|
|
22
|
+
#queue = [];
|
|
23
|
+
#running = false;
|
|
24
|
+
/** @type {Record<string, *>} */
|
|
25
|
+
#timeouts = {};
|
|
26
|
+
/** @type {Set<string>} */
|
|
27
|
+
#blacklist = new Set();
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Returns whether the queue is currently processing a task.
|
|
31
|
+
*
|
|
32
|
+
* @returns {boolean}
|
|
33
|
+
*/
|
|
34
|
+
isRunning() {
|
|
35
|
+
return this.#running;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Processes the next task in the queue if not already running.
|
|
40
|
+
* Ensures tasks are executed in order, one at a time.
|
|
41
|
+
*
|
|
42
|
+
* @returns {Promise<void>}
|
|
43
|
+
*/
|
|
44
|
+
async #processQueue() {
|
|
45
|
+
if (this.#running || this.#queue.length === 0) return;
|
|
46
|
+
this.#running = true;
|
|
47
|
+
const data = this.#queue.shift();
|
|
48
|
+
if (
|
|
49
|
+
data &&
|
|
50
|
+
typeof data.task === 'function' &&
|
|
51
|
+
typeof data.resolve === 'function' &&
|
|
52
|
+
typeof data.reject === 'function'
|
|
53
|
+
) {
|
|
54
|
+
const { task, resolve, reject, delay, id } = data;
|
|
55
|
+
try {
|
|
56
|
+
if (delay && id) {
|
|
57
|
+
await new Promise((resolveDelay) => {
|
|
58
|
+
const timeoutId = setTimeout(() => {
|
|
59
|
+
delete this.#timeouts[id];
|
|
60
|
+
resolveDelay(null);
|
|
61
|
+
}, delay);
|
|
62
|
+
this.#timeouts[id] = timeoutId;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (id && this.#blacklist.has(id)) {
|
|
67
|
+
reject(new Error('The function was canceled on TinyPromiseQueue.'));
|
|
68
|
+
this.#blacklist.delete(id);
|
|
69
|
+
this.#running = false;
|
|
70
|
+
this.#processQueue();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const result = await task();
|
|
75
|
+
resolve(result);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
reject(error);
|
|
78
|
+
} finally {
|
|
79
|
+
this.#running = false;
|
|
80
|
+
this.#processQueue();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Returns the index of a task by its ID.
|
|
87
|
+
*
|
|
88
|
+
* @param {string} id The ID of the task to locate.
|
|
89
|
+
* @returns {number} The index of the task in the queue, or -1 if not found.
|
|
90
|
+
*/
|
|
91
|
+
getIndexById(id) {
|
|
92
|
+
return this.#queue.findIndex((item) => item.id === id);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Returns a list of IDs for all tasks currently in the queue.
|
|
97
|
+
*
|
|
98
|
+
* @returns {{ index: number, id: string }[]} An array of task IDs currently queued.
|
|
99
|
+
*/
|
|
100
|
+
getQueuedIds() {
|
|
101
|
+
// @ts-ignore
|
|
102
|
+
return this.#queue
|
|
103
|
+
.map((item, index) => ({ index, id: item.id }))
|
|
104
|
+
.filter((entry) => typeof entry.id === 'string');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Reorders a task in the queue from one index to another.
|
|
109
|
+
*
|
|
110
|
+
* @param {number} fromIndex The current index of the task to move.
|
|
111
|
+
* @param {number} toIndex The index where the task should be placed.
|
|
112
|
+
*/
|
|
113
|
+
reorderQueue(fromIndex, toIndex) {
|
|
114
|
+
if (
|
|
115
|
+
typeof fromIndex !== 'number' ||
|
|
116
|
+
typeof toIndex !== 'number' ||
|
|
117
|
+
fromIndex < 0 ||
|
|
118
|
+
toIndex < 0 ||
|
|
119
|
+
fromIndex >= this.#queue.length ||
|
|
120
|
+
toIndex >= this.#queue.length
|
|
121
|
+
)
|
|
122
|
+
return;
|
|
123
|
+
const [item] = this.#queue.splice(fromIndex, 1);
|
|
124
|
+
this.#queue.splice(toIndex, 0, item);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Adds a new async task to the queue and ensures it runs in order after previous tasks.
|
|
129
|
+
* Optionally, a delay can be added before the task is executed.
|
|
130
|
+
*
|
|
131
|
+
* If the task is canceled before execution, it will be rejected with the message:
|
|
132
|
+
* "The function was canceled on TinyPromiseQueue."
|
|
133
|
+
*
|
|
134
|
+
* @param {(...args: any[]) => Promise<any>} task A function that returns a Promise to be executed sequentially.
|
|
135
|
+
* @param {number|null} [delay] Optional delay (in ms) before the task is executed.
|
|
136
|
+
* @param {string} [id] Optional ID to identify the task in the queue.
|
|
137
|
+
* @returns {Promise<any>} A Promise that resolves or rejects with the result of the task once it's processed.
|
|
138
|
+
*/
|
|
139
|
+
enqueue(task, delay, id) {
|
|
140
|
+
return new Promise((resolve, reject) => {
|
|
141
|
+
this.#queue.push({ task, resolve, reject, id, delay });
|
|
142
|
+
this.#processQueue();
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Cancels a scheduled delay and removes the task from the queue.
|
|
148
|
+
* Adds the ID to a blacklist so the task is skipped if already being processed.
|
|
149
|
+
*
|
|
150
|
+
* @param {string} id The ID of the task to cancel.
|
|
151
|
+
* @returns {boolean} True if a delay was cancelled and the task was removed.
|
|
152
|
+
*/
|
|
153
|
+
cancelTask(id) {
|
|
154
|
+
if (!id) return false;
|
|
155
|
+
let cancelled = false;
|
|
156
|
+
|
|
157
|
+
if (id in this.#timeouts) {
|
|
158
|
+
clearTimeout(this.#timeouts[id]);
|
|
159
|
+
delete this.#timeouts[id];
|
|
160
|
+
cancelled = true;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const index = this.getIndexById(id);
|
|
164
|
+
if (index !== -1) {
|
|
165
|
+
this.#queue.splice(index, 1);
|
|
166
|
+
cancelled = true;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (cancelled) this.#blacklist.add(id);
|
|
170
|
+
|
|
171
|
+
return cancelled;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
module.exports = TinyPromiseQueue;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export default TinyPromiseQueue;
|
|
2
|
+
/**
|
|
3
|
+
* A queue system for managing and executing asynchronous tasks sequentially, one at a time.
|
|
4
|
+
*
|
|
5
|
+
* Tasks can be delayed, reordered, canceled, and processed in strict order. The queue ensures that each task
|
|
6
|
+
* is executed after the previous one finishes, and any task can be skipped or canceled if needed.
|
|
7
|
+
*
|
|
8
|
+
* @class
|
|
9
|
+
*/
|
|
10
|
+
declare class TinyPromiseQueue {
|
|
11
|
+
/**
|
|
12
|
+
* Returns whether the queue is currently processing a task.
|
|
13
|
+
*
|
|
14
|
+
* @returns {boolean}
|
|
15
|
+
*/
|
|
16
|
+
isRunning(): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Returns the index of a task by its ID.
|
|
19
|
+
*
|
|
20
|
+
* @param {string} id The ID of the task to locate.
|
|
21
|
+
* @returns {number} The index of the task in the queue, or -1 if not found.
|
|
22
|
+
*/
|
|
23
|
+
getIndexById(id: string): number;
|
|
24
|
+
/**
|
|
25
|
+
* Returns a list of IDs for all tasks currently in the queue.
|
|
26
|
+
*
|
|
27
|
+
* @returns {{ index: number, id: string }[]} An array of task IDs currently queued.
|
|
28
|
+
*/
|
|
29
|
+
getQueuedIds(): {
|
|
30
|
+
index: number;
|
|
31
|
+
id: string;
|
|
32
|
+
}[];
|
|
33
|
+
/**
|
|
34
|
+
* Reorders a task in the queue from one index to another.
|
|
35
|
+
*
|
|
36
|
+
* @param {number} fromIndex The current index of the task to move.
|
|
37
|
+
* @param {number} toIndex The index where the task should be placed.
|
|
38
|
+
*/
|
|
39
|
+
reorderQueue(fromIndex: number, toIndex: number): void;
|
|
40
|
+
/**
|
|
41
|
+
* Adds a new async task to the queue and ensures it runs in order after previous tasks.
|
|
42
|
+
* Optionally, a delay can be added before the task is executed.
|
|
43
|
+
*
|
|
44
|
+
* If the task is canceled before execution, it will be rejected with the message:
|
|
45
|
+
* "The function was canceled on TinyPromiseQueue."
|
|
46
|
+
*
|
|
47
|
+
* @param {(...args: any[]) => Promise<any>} task A function that returns a Promise to be executed sequentially.
|
|
48
|
+
* @param {number|null} [delay] Optional delay (in ms) before the task is executed.
|
|
49
|
+
* @param {string} [id] Optional ID to identify the task in the queue.
|
|
50
|
+
* @returns {Promise<any>} A Promise that resolves or rejects with the result of the task once it's processed.
|
|
51
|
+
*/
|
|
52
|
+
enqueue(task: (...args: any[]) => Promise<any>, delay?: number | null, id?: string): Promise<any>;
|
|
53
|
+
/**
|
|
54
|
+
* Cancels a scheduled delay and removes the task from the queue.
|
|
55
|
+
* Adds the ID to a blacklist so the task is skipped if already being processed.
|
|
56
|
+
*
|
|
57
|
+
* @param {string} id The ID of the task to cancel.
|
|
58
|
+
* @returns {boolean} True if a delay was cancelled and the task was removed.
|
|
59
|
+
*/
|
|
60
|
+
cancelTask(id: string): boolean;
|
|
61
|
+
#private;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=TinyPromiseQueue.d.mts.map
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A queue system for managing and executing asynchronous tasks sequentially, one at a time.
|
|
3
|
+
*
|
|
4
|
+
* Tasks can be delayed, reordered, canceled, and processed in strict order. The queue ensures that each task
|
|
5
|
+
* is executed after the previous one finishes, and any task can be skipped or canceled if needed.
|
|
6
|
+
*
|
|
7
|
+
* @class
|
|
8
|
+
*/
|
|
9
|
+
class TinyPromiseQueue {
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {Object} QueuedTask
|
|
12
|
+
* @property {() => Promise<any>} task - The async task to execute.
|
|
13
|
+
* @property {(value: any) => any} resolve - The resolve function from the Promise.
|
|
14
|
+
* @property {(reason?: any) => any} reject - The reject function from the Promise.
|
|
15
|
+
* @property {string|undefined} [id] - Optional identifier for the task.
|
|
16
|
+
* @property {number|null|undefined} [delay] - Optional delay (in ms) before the task is executed.
|
|
17
|
+
*/
|
|
18
|
+
/** @type {Array<QueuedTask>} */
|
|
19
|
+
#queue = [];
|
|
20
|
+
#running = false;
|
|
21
|
+
/** @type {Record<string, *>} */
|
|
22
|
+
#timeouts = {};
|
|
23
|
+
/** @type {Set<string>} */
|
|
24
|
+
#blacklist = new Set();
|
|
25
|
+
/**
|
|
26
|
+
* Returns whether the queue is currently processing a task.
|
|
27
|
+
*
|
|
28
|
+
* @returns {boolean}
|
|
29
|
+
*/
|
|
30
|
+
isRunning() {
|
|
31
|
+
return this.#running;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Processes the next task in the queue if not already running.
|
|
35
|
+
* Ensures tasks are executed in order, one at a time.
|
|
36
|
+
*
|
|
37
|
+
* @returns {Promise<void>}
|
|
38
|
+
*/
|
|
39
|
+
async #processQueue() {
|
|
40
|
+
if (this.#running || this.#queue.length === 0)
|
|
41
|
+
return;
|
|
42
|
+
this.#running = true;
|
|
43
|
+
const data = this.#queue.shift();
|
|
44
|
+
if (data &&
|
|
45
|
+
typeof data.task === 'function' &&
|
|
46
|
+
typeof data.resolve === 'function' &&
|
|
47
|
+
typeof data.reject === 'function') {
|
|
48
|
+
const { task, resolve, reject, delay, id } = data;
|
|
49
|
+
try {
|
|
50
|
+
if (delay && id) {
|
|
51
|
+
await new Promise((resolveDelay) => {
|
|
52
|
+
const timeoutId = setTimeout(() => {
|
|
53
|
+
delete this.#timeouts[id];
|
|
54
|
+
resolveDelay(null);
|
|
55
|
+
}, delay);
|
|
56
|
+
this.#timeouts[id] = timeoutId;
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
if (id && this.#blacklist.has(id)) {
|
|
60
|
+
reject(new Error('The function was canceled on TinyPromiseQueue.'));
|
|
61
|
+
this.#blacklist.delete(id);
|
|
62
|
+
this.#running = false;
|
|
63
|
+
this.#processQueue();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const result = await task();
|
|
67
|
+
resolve(result);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
reject(error);
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
this.#running = false;
|
|
74
|
+
this.#processQueue();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Returns the index of a task by its ID.
|
|
80
|
+
*
|
|
81
|
+
* @param {string} id The ID of the task to locate.
|
|
82
|
+
* @returns {number} The index of the task in the queue, or -1 if not found.
|
|
83
|
+
*/
|
|
84
|
+
getIndexById(id) {
|
|
85
|
+
return this.#queue.findIndex((item) => item.id === id);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Returns a list of IDs for all tasks currently in the queue.
|
|
89
|
+
*
|
|
90
|
+
* @returns {{ index: number, id: string }[]} An array of task IDs currently queued.
|
|
91
|
+
*/
|
|
92
|
+
getQueuedIds() {
|
|
93
|
+
// @ts-ignore
|
|
94
|
+
return this.#queue
|
|
95
|
+
.map((item, index) => ({ index, id: item.id }))
|
|
96
|
+
.filter((entry) => typeof entry.id === 'string');
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Reorders a task in the queue from one index to another.
|
|
100
|
+
*
|
|
101
|
+
* @param {number} fromIndex The current index of the task to move.
|
|
102
|
+
* @param {number} toIndex The index where the task should be placed.
|
|
103
|
+
*/
|
|
104
|
+
reorderQueue(fromIndex, toIndex) {
|
|
105
|
+
if (typeof fromIndex !== 'number' ||
|
|
106
|
+
typeof toIndex !== 'number' ||
|
|
107
|
+
fromIndex < 0 ||
|
|
108
|
+
toIndex < 0 ||
|
|
109
|
+
fromIndex >= this.#queue.length ||
|
|
110
|
+
toIndex >= this.#queue.length)
|
|
111
|
+
return;
|
|
112
|
+
const [item] = this.#queue.splice(fromIndex, 1);
|
|
113
|
+
this.#queue.splice(toIndex, 0, item);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Adds a new async task to the queue and ensures it runs in order after previous tasks.
|
|
117
|
+
* Optionally, a delay can be added before the task is executed.
|
|
118
|
+
*
|
|
119
|
+
* If the task is canceled before execution, it will be rejected with the message:
|
|
120
|
+
* "The function was canceled on TinyPromiseQueue."
|
|
121
|
+
*
|
|
122
|
+
* @param {(...args: any[]) => Promise<any>} task A function that returns a Promise to be executed sequentially.
|
|
123
|
+
* @param {number|null} [delay] Optional delay (in ms) before the task is executed.
|
|
124
|
+
* @param {string} [id] Optional ID to identify the task in the queue.
|
|
125
|
+
* @returns {Promise<any>} A Promise that resolves or rejects with the result of the task once it's processed.
|
|
126
|
+
*/
|
|
127
|
+
enqueue(task, delay, id) {
|
|
128
|
+
return new Promise((resolve, reject) => {
|
|
129
|
+
this.#queue.push({ task, resolve, reject, id, delay });
|
|
130
|
+
this.#processQueue();
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Cancels a scheduled delay and removes the task from the queue.
|
|
135
|
+
* Adds the ID to a blacklist so the task is skipped if already being processed.
|
|
136
|
+
*
|
|
137
|
+
* @param {string} id The ID of the task to cancel.
|
|
138
|
+
* @returns {boolean} True if a delay was cancelled and the task was removed.
|
|
139
|
+
*/
|
|
140
|
+
cancelTask(id) {
|
|
141
|
+
if (!id)
|
|
142
|
+
return false;
|
|
143
|
+
let cancelled = false;
|
|
144
|
+
if (id in this.#timeouts) {
|
|
145
|
+
clearTimeout(this.#timeouts[id]);
|
|
146
|
+
delete this.#timeouts[id];
|
|
147
|
+
cancelled = true;
|
|
148
|
+
}
|
|
149
|
+
const index = this.getIndexById(id);
|
|
150
|
+
if (index !== -1) {
|
|
151
|
+
this.#queue.splice(index, 1);
|
|
152
|
+
cancelled = true;
|
|
153
|
+
}
|
|
154
|
+
if (cancelled)
|
|
155
|
+
this.#blacklist.add(id);
|
|
156
|
+
return cancelled;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
export default TinyPromiseQueue;
|
package/docs/README.md
CHANGED
|
@@ -17,6 +17,11 @@ This folder contains the core scripts we have worked on so far. Each file is a m
|
|
|
17
17
|
- 🧠 **[objFilter.md](./basics/objFilter.md)** — Type detection, extension, and analysis made easy with simple and extensible type validation.
|
|
18
18
|
- 🔢 **[simpleMath.md](./basics/simpleMath.md)** — A collection of simple math utilities for calculations like the Rule of Three and percentages.
|
|
19
19
|
- ✍️ **[text.md](./basics/text.md)** — A utility for transforming text into title case formats, with multiple options for capitalization.
|
|
20
|
+
- 🔄 **[asyncReplace.md](./basics/asyncReplace.md)** — Asynchronously replaces matches in a string using a regex and an async function.
|
|
21
|
+
|
|
22
|
+
### 2. **`libs/`**
|
|
23
|
+
- 🗂️ **[TinyPromiseQueue.md](./libs/TinyPromiseQueue.md)** — A class that allows sequential execution of asynchronous tasks, supporting task delays, cancellation, and queue management.
|
|
24
|
+
- 🏅 **[TinyLevelUp.md](./libs/TinyLevelUp.md)** — A class to manage user level-up logic based on experience points, providing methods for experience validation, addition, removal, and calculation.
|
|
20
25
|
|
|
21
26
|
---
|
|
22
27
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
## `asyncReplace(str, regex, asyncFn)` 🔄
|
|
2
|
+
|
|
3
|
+
Asynchronously replaces matches in a string using a regular expression and an async function.
|
|
4
|
+
|
|
5
|
+
This function performs replacements on a string, allowing each match to be asynchronously replaced by calling an asynchronous function for each match. The asynchronous function should return a replacement value for each match and will receive the same arguments as the standard `replace` callback.
|
|
6
|
+
|
|
7
|
+
### Parameters:
|
|
8
|
+
|
|
9
|
+
- `str` (`string`): The input string to perform replacements on.
|
|
10
|
+
- `regex` (`RegExp`): The regular expression used to match substrings for replacement.
|
|
11
|
+
- `asyncFn` (`Function`): An asynchronous function that returns a replacement for each match.
|
|
12
|
+
- It receives the same arguments as the standard `replace` callback (the matched substring and the matched string's groups).
|
|
13
|
+
- The function should return a `Promise` that resolves to the replacement value for that match.
|
|
14
|
+
|
|
15
|
+
### Returns:
|
|
16
|
+
- `Promise<string>`: A promise that resolves to the resulting string with all async replacements applied.
|
|
17
|
+
|
|
18
|
+
### Example:
|
|
19
|
+
|
|
20
|
+
```javascript
|
|
21
|
+
await asyncReplace("Hello @user1 and @user2!", /@\w+/g, async (mention) => {
|
|
22
|
+
return await getUserNameFromMention(mention);
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
In this example, each `@user` mention is asynchronously replaced by the value returned from `getUserNameFromMention`.
|
|
27
|
+
|
|
28
|
+
### Description:
|
|
29
|
+
|
|
30
|
+
This function will:
|
|
31
|
+
1. Use a regular expression (`regex`) to find all matches in the input string (`str`).
|
|
32
|
+
2. For each match, it will invoke the provided asynchronous function (`asyncFn`), which should return the replacement value.
|
|
33
|
+
3. Once all promises are resolved, it replaces the original matches in the string with the resolved values.
|
|
34
|
+
|
|
35
|
+
This is useful for scenarios where you need to replace parts of a string based on dynamic data (like fetching usernames from a server for each mention in a message).
|
|
36
|
+
|
|
37
|
+
### Notes:
|
|
38
|
+
- The replacements are performed asynchronously, ensuring non-blocking behavior when dealing with large or external data sources.
|
|
39
|
+
- The function utilizes `Promise.all` to handle multiple asynchronous operations concurrently before replacing the matches in the original string.
|