@rzl-zone/utils-js 3.12.0 → 3.12.1-beta.1
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/{LICENSE.md → LICENSE} +3 -3
- package/README.md +69 -96
- package/dist/.references/index.d.cts +25 -0
- package/dist/.references/index.d.ts +25 -0
- package/dist/assertIsArray-DJXkjHZs.cjs +26 -0
- package/dist/assertIsArray-DJXkjHZs.cjs.map +1 -0
- package/dist/assertIsArray-bTA3XLjq.js +20 -0
- package/dist/assertIsArray-bTA3XLjq.js.map +1 -0
- package/dist/assertIsBoolean-C8WEXVr2.cjs +1283 -0
- package/dist/assertIsBoolean-C8WEXVr2.cjs.map +1 -0
- package/dist/assertIsBoolean-DR1SaXPD.js +1073 -0
- package/dist/assertIsBoolean-DR1SaXPD.js.map +1 -0
- package/dist/assertIsString-BiHQSrB2.cjs +26 -0
- package/dist/assertIsString-BiHQSrB2.cjs.map +1 -0
- package/dist/assertIsString-CEB07_83.js +20 -0
- package/dist/assertIsString-CEB07_83.js.map +1 -0
- package/dist/assertions/index.cjs +37 -40
- package/dist/assertions/index.cjs.map +1 -0
- package/dist/assertions/index.d.cts +12 -0
- package/dist/assertions/index.d.ts +10 -824
- package/dist/assertions/index.js +30 -13
- package/dist/assertions/index.js.map +1 -0
- package/dist/conversions/index.cjs +34 -103
- package/dist/conversions/index.d.cts +12 -0
- package/dist/conversions/index.d.ts +10 -1791
- package/dist/conversions/index.js +14 -24
- package/dist/conversions-BNIh_tCH.js +380 -0
- package/dist/conversions-BNIh_tCH.js.map +1 -0
- package/dist/conversions-D_Kh0a_C.cjs +446 -0
- package/dist/conversions-D_Kh0a_C.cjs.map +1 -0
- package/dist/events/index.cjs +55 -31
- package/dist/events/index.cjs.map +1 -0
- package/dist/events/index.d.cts +176 -0
- package/dist/events/index.d.ts +164 -166
- package/dist/events/index.js +50 -12
- package/dist/events/index.js.map +1 -0
- package/dist/formatEnvPort-B3OLxQk9.cjs +171 -0
- package/dist/formatEnvPort-B3OLxQk9.cjs.map +1 -0
- package/dist/formatEnvPort-ByFVLjSV.js +159 -0
- package/dist/formatEnvPort-ByFVLjSV.js.map +1 -0
- package/dist/formatters/index.cjs +21 -61
- package/dist/formatters/index.d.cts +12 -0
- package/dist/formatters/index.d.ts +10 -2152
- package/dist/formatters/index.js +10 -18
- package/dist/formatters--1m_vpE8.js +369 -0
- package/dist/formatters--1m_vpE8.js.map +1 -0
- package/dist/formatters-Cbij0XLU.cjs +429 -0
- package/dist/formatters-Cbij0XLU.cjs.map +1 -0
- package/dist/generators/index.cjs +165 -41
- package/dist/generators/index.cjs.map +1 -0
- package/dist/generators/index.d.cts +12 -0
- package/dist/generators/index.d.ts +10 -338
- package/dist/generators/index.js +158 -14
- package/dist/generators/index.js.map +1 -0
- package/dist/index-59zbLcPr.d.ts +340 -0
- package/dist/index-B6tawc8L.d.cts +1716 -0
- package/dist/index-C267akkJ.d.ts +2158 -0
- package/dist/index-CeBC2Vvl.d.cts +2361 -0
- package/dist/index-CgRDTI6f.d.ts +822 -0
- package/dist/index-CoiUBVmr.d.ts +720 -0
- package/dist/index-D4fcasfZ.d.cts +720 -0
- package/dist/index-DDrSQKIc.d.ts +1716 -0
- package/dist/index-DsGxO31H.d.cts +765 -0
- package/dist/index-Hg1qJkjl.d.ts +765 -0
- package/dist/index-Qm3iFwd0.d.cts +2158 -0
- package/dist/index-UPp94Agr.d.ts +2361 -0
- package/dist/index-gBA_8SuF.d.cts +340 -0
- package/dist/index-jyDqzicx.d.cts +822 -0
- package/dist/isBigInt-C4krUeAw.cjs +20 -0
- package/dist/isBigInt-C4krUeAw.cjs.map +1 -0
- package/dist/isBigInt-DKe0M6hp.js +14 -0
- package/dist/isBigInt-DKe0M6hp.js.map +1 -0
- package/dist/isEmptyObject-DCipFwxJ.js +25 -0
- package/dist/isEmptyObject-DCipFwxJ.js.map +1 -0
- package/dist/isEmptyObject-ZkSwRC_D.cjs +37 -0
- package/dist/isEmptyObject-ZkSwRC_D.cjs.map +1 -0
- package/dist/isEmptyString-BXzKAC2j.js +15 -0
- package/dist/isEmptyString-BXzKAC2j.js.map +1 -0
- package/dist/isEmptyString-UiiUsSQj.cjs +21 -0
- package/dist/isEmptyString-UiiUsSQj.cjs.map +1 -0
- package/dist/isEmptyValue-BQzcjVaL.cjs +30 -0
- package/dist/isEmptyValue-BQzcjVaL.cjs.map +1 -0
- package/dist/isEmptyValue-jqOr7OHD.js +24 -0
- package/dist/isEmptyValue-jqOr7OHD.js.map +1 -0
- package/dist/isEqual-BX49cF9m.js +87 -0
- package/dist/isEqual-BX49cF9m.js.map +1 -0
- package/dist/isEqual-BvumA3RA.cjs +111 -0
- package/dist/isEqual-BvumA3RA.cjs.map +1 -0
- package/dist/isFinite-BCnaDpod.js +15 -0
- package/dist/isFinite-BCnaDpod.js.map +1 -0
- package/dist/isFinite-D24ZaE6c.cjs +21 -0
- package/dist/isFinite-D24ZaE6c.cjs.map +1 -0
- package/dist/isInteger-Caeuz0rB.cjs +20 -0
- package/dist/isInteger-Caeuz0rB.cjs.map +1 -0
- package/dist/isInteger-naMbJsxJ.js +14 -0
- package/dist/isInteger-naMbJsxJ.js.map +1 -0
- package/dist/isPlainObject-BF-2-phb.d.cts +339 -0
- package/dist/isPlainObject-DxNDL8XU.d.ts +339 -0
- package/dist/isServer-BJHVnixd.cjs +20 -0
- package/dist/isServer-BJHVnixd.cjs.map +1 -0
- package/dist/isServer-Da3o3XSs.js +14 -0
- package/dist/isServer-Da3o3XSs.js.map +1 -0
- package/dist/isTypedArray-DuNA8tK6.js +31 -0
- package/dist/isTypedArray-DuNA8tK6.js.map +1 -0
- package/dist/isTypedArray-TJptiw2b.cjs +43 -0
- package/dist/isTypedArray-TJptiw2b.cjs.map +1 -0
- package/dist/isURL-C-kSk6KJ.js +14 -0
- package/dist/isURL-C-kSk6KJ.js.map +1 -0
- package/dist/isURL-DeUPO_oR.cjs +20 -0
- package/dist/isURL-DeUPO_oR.cjs.map +1 -0
- package/dist/isValidDomain-BB9IGhJs.cjs +1845 -0
- package/dist/isValidDomain-BB9IGhJs.cjs.map +1 -0
- package/dist/isValidDomain-DoE98yhJ.js +1827 -0
- package/dist/isValidDomain-DoE98yhJ.js.map +1 -0
- package/dist/next/index.cjs +119 -214
- package/dist/next/index.cjs.map +1 -0
- package/dist/next/index.d.cts +220 -0
- package/dist/next/index.d.ts +203 -214
- package/dist/next/index.js +117 -212
- package/dist/next/index.js.map +1 -0
- package/dist/next/server/index.cjs +25 -40
- package/dist/next/server/index.cjs.map +1 -0
- package/dist/next/server/index.d.cts +39 -0
- package/dist/next/server/index.d.ts +34 -35
- package/dist/next/server/index.js +23 -38
- package/dist/next/server/index.js.map +1 -0
- package/dist/noop-B13_ii35.cjs +18 -0
- package/dist/noop-B13_ii35.cjs.map +1 -0
- package/dist/noop-ubqAIbHD.js +12 -0
- package/dist/noop-ubqAIbHD.js.map +1 -0
- package/dist/normalizeSpaces-Bg2IZW7W.js +23 -0
- package/dist/normalizeSpaces-Bg2IZW7W.js.map +1 -0
- package/dist/normalizeSpaces-ZXnR4Qzp.cjs +29 -0
- package/dist/normalizeSpaces-ZXnR4Qzp.cjs.map +1 -0
- package/dist/normalizeString-BDdkaXui.js +15 -0
- package/dist/normalizeString-BDdkaXui.js.map +1 -0
- package/dist/normalizeString-BE6ELqEb.cjs +21 -0
- package/dist/normalizeString-BE6ELqEb.cjs.map +1 -0
- package/dist/operations/index.cjs +65 -32
- package/dist/operations/index.cjs.map +1 -0
- package/dist/operations/index.d.cts +139 -0
- package/dist/operations/index.d.ts +129 -134
- package/dist/operations/index.js +61 -17
- package/dist/operations/index.js.map +1 -0
- package/dist/parsers/index.cjs +12 -19
- package/dist/parsers/index.d.cts +239 -0
- package/dist/parsers/index.d.ts +234 -235
- package/dist/parsers/index.js +10 -12
- package/dist/parsers-BSBPgvsq.js +643 -0
- package/dist/parsers-BSBPgvsq.js.map +1 -0
- package/dist/parsers-OqDeffqc.cjs +649 -0
- package/dist/parsers-OqDeffqc.cjs.map +1 -0
- package/dist/parsing-Cao8b358.js +50 -0
- package/dist/parsing-Cao8b358.js.map +1 -0
- package/dist/parsing-DOGSCH6N.cjs +56 -0
- package/dist/parsing-DOGSCH6N.cjs.map +1 -0
- package/dist/predicates/index.cjs +91 -296
- package/dist/predicates/index.d.cts +13 -0
- package/dist/predicates/index.d.ts +12 -2482
- package/dist/predicates/index.js +23 -25
- package/dist/predicates-Bj6meyXV.js +256 -0
- package/dist/predicates-Bj6meyXV.js.map +1 -0
- package/dist/predicates-D0ubqgqy.cjs +412 -0
- package/dist/predicates-D0ubqgqy.cjs.map +1 -0
- package/dist/promises/index.cjs +76 -24
- package/dist/promises/index.cjs.map +1 -0
- package/dist/promises/index.d.cts +123 -0
- package/dist/promises/index.d.ts +116 -119
- package/dist/promises/index.js +73 -13
- package/dist/promises/index.js.map +1 -0
- package/dist/punyCode-8SrbMWfM.js +179 -0
- package/dist/punyCode-8SrbMWfM.js.map +1 -0
- package/dist/punyCode-D-Qu6nj6.cjs +185 -0
- package/dist/punyCode-D-Qu6nj6.cjs.map +1 -0
- package/dist/removeSpaces-Bmc5DX4F.js +19 -0
- package/dist/removeSpaces-Bmc5DX4F.js.map +1 -0
- package/dist/removeSpaces-CWIvhZHg.cjs +25 -0
- package/dist/removeSpaces-CWIvhZHg.cjs.map +1 -0
- package/dist/rzl-utils.global.js +20 -9
- package/dist/safeJsonParse-BP38mwlj.js +184 -0
- package/dist/safeJsonParse-BP38mwlj.js.map +1 -0
- package/dist/safeJsonParse-Sms2CJf4.cjs +208 -0
- package/dist/safeJsonParse-Sms2CJf4.cjs.map +1 -0
- package/dist/safeStableStringify-CJtP89qn.cjs +106 -0
- package/dist/safeStableStringify-CJtP89qn.cjs.map +1 -0
- package/dist/safeStableStringify-CXOZ9Ub8.js +88 -0
- package/dist/safeStableStringify-CXOZ9Ub8.js.map +1 -0
- package/dist/strings/index.cjs +79 -81
- package/dist/strings/index.cjs.map +1 -0
- package/dist/strings/index.d.cts +12 -0
- package/dist/strings/index.d.ts +10 -775
- package/dist/strings/index.js +62 -14
- package/dist/strings/index.js.map +1 -0
- package/dist/tailwind/index.cjs +19 -47
- package/dist/tailwind/index.d.cts +12 -0
- package/dist/tailwind/index.d.ts +11 -712
- package/dist/tailwind/index.js +10 -12
- package/dist/tailwind-B2ssevxq.js +199 -0
- package/dist/tailwind-B2ssevxq.js.map +1 -0
- package/dist/tailwind-CHIx9uxu.cjs +247 -0
- package/dist/tailwind-CHIx9uxu.cjs.map +1 -0
- package/dist/toStringArrayUnRecursive-C4zYCja7.cjs +51 -0
- package/dist/toStringArrayUnRecursive-C4zYCja7.cjs.map +1 -0
- package/dist/toStringArrayUnRecursive-DJGtPsFb.js +39 -0
- package/dist/toStringArrayUnRecursive-DJGtPsFb.js.map +1 -0
- package/dist/urls/index.cjs +130 -57
- package/dist/urls/index.cjs.map +1 -0
- package/dist/urls/index.d.cts +737 -0
- package/dist/urls/index.d.ts +699 -708
- package/dist/urls/index.js +122 -26
- package/dist/urls/index.js.map +1 -0
- package/package.json +203 -194
- package/dist/chunk-2AFQ33D3.cjs +0 -64
- package/dist/chunk-2CYDJVGM.js +0 -246
- package/dist/chunk-2MW4JDQ2.cjs +0 -598
- package/dist/chunk-2VTDXC3N.cjs +0 -1825
- package/dist/chunk-44XX2P34.js +0 -209
- package/dist/chunk-4YLBKLGS.cjs +0 -18
- package/dist/chunk-566CXQW7.cjs +0 -560
- package/dist/chunk-57EPKYID.cjs +0 -397
- package/dist/chunk-5MGEC3YG.js +0 -63
- package/dist/chunk-6EF52423.cjs +0 -249
- package/dist/chunk-6SCOKU3S.js +0 -109
- package/dist/chunk-6VUXD3CF.js +0 -119
- package/dist/chunk-7B76BSNK.cjs +0 -118
- package/dist/chunk-7Y6I2DSU.cjs +0 -101
- package/dist/chunk-A7S7E2EE.cjs +0 -308
- package/dist/chunk-AJZ6PMMZ.js +0 -16
- package/dist/chunk-AXGBL2IO.cjs +0 -251
- package/dist/chunk-B4TC6FBV.cjs +0 -678
- package/dist/chunk-BAV5T2E3.cjs +0 -15
- package/dist/chunk-BKIJBNIE.js +0 -21
- package/dist/chunk-BNIMTFK5.js +0 -59
- package/dist/chunk-BXW7YXB7.js +0 -1823
- package/dist/chunk-CFYZC4S6.js +0 -53
- package/dist/chunk-CSG4SCL3.js +0 -1587
- package/dist/chunk-CWQW7AKK.js +0 -676
- package/dist/chunk-DVMHRLKP.cjs +0 -16
- package/dist/chunk-EN7LVZBZ.js +0 -548
- package/dist/chunk-EV4Y7HCY.cjs +0 -26
- package/dist/chunk-F66VDYIZ.cjs +0 -18
- package/dist/chunk-FLJX37EL.cjs +0 -30
- package/dist/chunk-GKC3UDMC.cjs +0 -1623
- package/dist/chunk-H65I3GRZ.cjs +0 -106
- package/dist/chunk-HHYWB7VZ.js +0 -24
- package/dist/chunk-HNGGISFL.cjs +0 -65
- package/dist/chunk-HNSQAVSZ.cjs +0 -35
- package/dist/chunk-HSP6IWZK.js +0 -17
- package/dist/chunk-IDZS7J6T.js +0 -242
- package/dist/chunk-JS6R55VL.js +0 -302
- package/dist/chunk-JZVT5FK7.js +0 -232
- package/dist/chunk-KHO2SBNA.cjs +0 -16
- package/dist/chunk-KIDJCMNJ.js +0 -33
- package/dist/chunk-KOLEURVT.cjs +0 -38
- package/dist/chunk-L4V53MQK.cjs +0 -269
- package/dist/chunk-L5RDAVVH.js +0 -14
- package/dist/chunk-NODTV4F3.js +0 -16
- package/dist/chunk-NYK5K3V2.cjs +0 -211
- package/dist/chunk-ODUO3RTL.cjs +0 -113
- package/dist/chunk-ONZFBJVW.js +0 -14
- package/dist/chunk-PFXCTE37.js +0 -28
- package/dist/chunk-PPST7QAQ.js +0 -587
- package/dist/chunk-Q5IMYDFL.cjs +0 -33
- package/dist/chunk-QFFBIOJ4.js +0 -31
- package/dist/chunk-QNKGP5DY.js +0 -14
- package/dist/chunk-RRQHMOPE.cjs +0 -19
- package/dist/chunk-RU5OSRBU.js +0 -95
- package/dist/chunk-SDMPEJ4F.js +0 -35
- package/dist/chunk-SYNL5IKP.js +0 -115
- package/dist/chunk-TCDOWZQE.js +0 -16
- package/dist/chunk-TQPGXGKB.cjs +0 -123
- package/dist/chunk-TULOI4GL.js +0 -370
- package/dist/chunk-UBHCP4N5.cjs +0 -36
- package/dist/chunk-UCHF3M34.cjs +0 -56
- package/dist/chunk-UDA26MCU.cjs +0 -16
- package/dist/chunk-V3C4FYZL.cjs +0 -18
- package/dist/chunk-VAAHZFBF.js +0 -32
- package/dist/chunk-VJDDGRIK.cjs +0 -16
- package/dist/chunk-WVSPXFTY.js +0 -14
- package/dist/chunk-WYP76WXB.js +0 -101
- package/dist/chunk-YDE4ZBB7.cjs +0 -237
- package/dist/chunk-YKQEOO7C.cjs +0 -23
- package/dist/chunk-YSZC56SZ.js +0 -264
- package/dist/chunk-YWHHVDT4.js +0 -13
- package/dist/index.d.ts +0 -24
- package/dist/isPlainObject-DTJVV2Kf.d.ts +0 -536
package/dist/promises/index.cjs
CHANGED
|
@@ -1,25 +1,77 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
require('../
|
|
14
|
-
require('../
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
2
|
+
* ========================================================================
|
|
3
|
+
* @rzl-zone/utils-js
|
|
4
|
+
* ------------------------------------------------------------------------
|
|
5
|
+
* Version: `3.12.1-beta.1`
|
|
6
|
+
* Author: `Rizalvin Dwiky <rizalvindwiky@gmail.com>`
|
|
7
|
+
* Repository: `https://github.com/rzl-zone/rzl-zone/tree/main/packages/utils-js`
|
|
8
|
+
* ========================================================================
|
|
9
|
+
*/
|
|
10
|
+
"use strict";
|
|
11
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
12
|
+
const require_assertIsBoolean = require('../assertIsBoolean-C8WEXVr2.cjs');
|
|
13
|
+
const require_safeStableStringify = require('../safeStableStringify-CJtP89qn.cjs');
|
|
14
|
+
const require_isInteger = require('../isInteger-Caeuz0rB.cjs');
|
|
15
|
+
var CustomPromise = class extends Promise {
|
|
16
|
+
_value;
|
|
17
|
+
_error;
|
|
18
|
+
_finish = [];
|
|
19
|
+
constructor(executor) {
|
|
20
|
+
let resolveOuter;
|
|
21
|
+
let rejectOuter;
|
|
22
|
+
super((resolve, reject) => {
|
|
23
|
+
resolveOuter = resolve;
|
|
24
|
+
rejectOuter = reject;
|
|
25
|
+
});
|
|
26
|
+
executor((v) => {
|
|
27
|
+
this._value = v;
|
|
28
|
+
resolveOuter(v);
|
|
29
|
+
this._finish.forEach((f) => f(v, void 0));
|
|
30
|
+
}, (e) => {
|
|
31
|
+
this._error = e;
|
|
32
|
+
rejectOuter(e);
|
|
33
|
+
this._finish.forEach((f) => f(void 0, e));
|
|
34
|
+
});
|
|
35
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
36
|
+
}
|
|
37
|
+
then(onfulfilled, onrejected) {
|
|
38
|
+
return super.then(onfulfilled, onrejected);
|
|
39
|
+
}
|
|
40
|
+
catch(onrejected) {
|
|
41
|
+
return super.catch(onrejected);
|
|
42
|
+
}
|
|
43
|
+
finish(cb) {
|
|
44
|
+
if (this._value !== void 0 || this._error !== void 0) cb(this._value, this._error);
|
|
45
|
+
else this._finish.push(cb);
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var AbortError = class extends Error {
|
|
50
|
+
constructor(message = "The operation was aborted", name = "AbortError") {
|
|
51
|
+
super(message);
|
|
52
|
+
this.name = name;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const delay = (milliSeconds = 1e3, signal) => {
|
|
56
|
+
if (!require_isInteger.isInteger(milliSeconds) || milliSeconds <= 0) throw new TypeError(`First parameter (\`milliSeconds\`) must be of type \`number\` and value must be a \`non-zero\`, \`non-NaN\`, \`non-negative\`, and \`integer-number\`, but received: \`${require_assertIsBoolean.getPreciseType(milliSeconds)}\`, with value: \`${require_safeStableStringify.safeStableStringify(milliSeconds, { keepUndefined: true })}\`.`);
|
|
57
|
+
if (require_assertIsBoolean.isNull(signal) || signal && !(signal instanceof AbortSignal)) throw new TypeError("Second parameter (`signal`) must be an `instance of AbortSignal` if provided.");
|
|
58
|
+
return new Promise((resolve, reject) => {
|
|
59
|
+
const timer = setTimeout(() => {
|
|
60
|
+
cleanup();
|
|
61
|
+
resolve();
|
|
62
|
+
}, milliSeconds);
|
|
63
|
+
const cleanup = () => {
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
if (signal) signal.removeEventListener("abort", onAbort);
|
|
66
|
+
};
|
|
67
|
+
const onAbort = () => {
|
|
68
|
+
cleanup();
|
|
69
|
+
reject(new AbortError("Function `delay` from `@rzl-zone/utils-js` was aborted.", "AbortError"));
|
|
70
|
+
};
|
|
71
|
+
if (signal) if (signal.aborted) onAbort();
|
|
72
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
exports.CustomPromise = CustomPromise;
|
|
76
|
+
exports.delay = delay;
|
|
77
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["isInteger","getPreciseType","safeStableStringify","isNull"],"sources":["../../src/promises/CustomPromise.ts","../../src/promises/delay.ts"],"sourcesContent":["import type { CustomPromiseType } from \"@rzl-zone/ts-types-plus\";\n\nexport type { CustomPromiseType };\n\n/** -------------------------------------------------------------\n * * ***Utility Class: `CustomPromise`.***\n * -------------------------------------------------------------\n * **A strongly typed extension of the native {@link Promise | **`Promise`**}.**\n * 1. **Behaves exactly like a normal Promise** for `then`/`catch`\n * and `await` semantics.\n * 2. **Stores the final resolution or rejection internally** so\n * it can be retrieved by a custom `finish` handler.\n * 3. **Adds a `finish` method** which runs once after settlement\n * with access to both the fulfilled value *and* the rejection\n * reason (only one will be defined).\n * - **Key Differences from a Native `Promise`:**\n * - Every call to `then`/`catch` returns **`CustomPromise`**\n * again, so the `finish` method remains available on the\n * entire chain.\n * - `finish` provides a tuple-like callback:\n * - `val` → defined when fulfilled.\n * - `err` → defined when rejected.\n * @template Success Type of the resolved value.\n * @template Error Type of the rejection reason (default `unknown`).\n * @example\n * ```ts\n * import { CustomPromise, type CustomPromiseType } from \"@rzl-zone/utils-js/promises\";\n *\n * type User = { id: number; name: string };\n * type ApiError = { message: string };\n *\n * function fetchUser(): CustomPromiseType<User, ApiError> {\n * return new CustomPromise<User, ApiError>((resolve, reject) => {\n * setTimeout(\n * () =>\n * void (Math.random() > 0.5\n * ? resolve({ id: 1, name: \"Alice\" })\n * : reject({ message: \"Random failure\" })),\n * 500\n * );\n * });\n * }\n *\n * fetchUser()\n * .then(user => {\n * console.log(\"SUCCESS:\", user);\n * return user;\n * })\n * .catch(err => {\n * console.error(\"ERROR:\", err);\n * throw err;\n * })\n * .finish((val, err) => {\n * // Runs once after settle, regardless of outcome\n * console.log(\"FINISH:\", { val, err });\n * });\n * ```\n * ---\n * - **Implementation Notes:**\n * - Uses `Object.setPrototypeOf` to preserve the prototype chain\n * for environments targeting ES5 or when subclassing Promise.\n * - Internal `_value` and `_error` are updated as soon as the\n * executor resolves or rejects, guaranteeing `finish` receives\n * the final state even when added after settlement.\n */\nexport class CustomPromise<Success, Error = unknown>\n extends Promise<Success>\n implements CustomPromiseType<Success, Error>\n{\n private _value?: Success;\n private _error?: Error;\n private _finish: Array<(v?: Success, e?: Error) => void> = [];\n\n constructor(\n executor: (\n resolve: (v: Success) => void,\n reject: (e: Error) => void\n ) => void\n ) {\n let resolveOuter!: (v: Success) => void;\n let rejectOuter!: (e: Error) => void;\n\n super((resolve, reject) => {\n resolveOuter = resolve;\n rejectOuter = reject;\n });\n\n executor(\n (v) => {\n this._value = v;\n resolveOuter(v);\n this._finish.forEach((f) => f(v, undefined));\n },\n (e) => {\n this._error = e;\n rejectOuter(e);\n this._finish.forEach((f) => f(undefined, e));\n }\n );\n\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n override then<TResult1 = Success, TResult2 = never>(\n onfulfilled?: ((value: Success) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: Error) => TResult2 | PromiseLike<TResult2>) | null\n ): CustomPromise<TResult1 | TResult2, Error> {\n return super.then(onfulfilled, onrejected) as unknown as CustomPromise<\n TResult1 | TResult2,\n Error\n >;\n }\n\n override catch<TResult = never>(\n onrejected?: ((reason: Error) => TResult | PromiseLike<TResult>) | null\n ): CustomPromise<Success | TResult, Error> {\n return super.catch(onrejected) as unknown as CustomPromise<\n Success | TResult,\n Error\n >;\n }\n\n /**\n * Registers a callback to be invoked **exactly once** when the\n * promise settles, with access to both the resolved value and\n * the rejection reason.\n *\n * If the promise is already settled when `finish` is called,\n * the callback executes immediately on the same tick.\n *\n * @param cb Callback receiving the final `(value, error)`.\n * @returns `this` for fluent chaining.\n */\n finish(cb: (val?: Success, err?: Error) => void): this {\n if (this._value !== undefined || this._error !== undefined) {\n cb(this._value, this._error);\n } else {\n this._finish.push(cb);\n }\n return this;\n }\n}\n","import { isNull } from \"@/predicates/is/isNull\";\nimport { isInteger } from \"@/predicates/is/isInteger\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\n\n/** -------------------------------------------------------------------\n * * ***Custom `AbortError` for cross-runtime delay cancellation.***\n * -------------------------------------------------------------------\n */\nclass AbortError extends Error {\n constructor(\n message: string = \"The operation was aborted\",\n name: string = \"AbortError\"\n ) {\n super(message);\n this.name = name;\n }\n}\n\n/** ------------------------------------------------------------\n * * ***Utility: `delay`.***\n * ------------------------------------------------------------\n * **Creates a Promise-based delay that resolves after a given number\n * of milliseconds, optionally supports cancellation with `AbortSignal`.**\n * - **Behavior:**\n * - Validates `milliSeconds` is a non-zero, non-negative integer.\n * - Validates `signal` is an `AbortSignal` instance when provided.\n * - Cleans up event listeners and timers properly.\n * @param {number} [milliSeconds=1000]\n * The duration of the delay in milliseconds, default is `1000`.\n * @param {AbortSignal} [signal]\n * An optional `AbortSignal` that can cancel the delay.\n * @returns {Promise<void>}\n * A promise that resolves after the specified delay or\n * rejects with an `AbortError` if aborted.\n * @throws **{@link TypeError | `TypeError`}** while validates `milliSeconds` and `signal`:\n * - If `milliSeconds` **is not a valid** an `integer-number`, `NaN`, `negative-number`, or `≤ 0`.\n * - If `signal` **is not a valid** an`AbortSignal`.\n * @throws **{@link DOMException | `DOMException`}** if the delay is aborted using the signal, rejects with `AbortError`.\n * @example\n * // Waits for 2 seconds\n * await delay(2000);\n *\n * // Delay with AbortSignal\n * const controller = new AbortController();\n * delay(5000, controller.signal).catch(err => console.log(err.name)); // \"AbortError\"\n * controller.abort();\n */\nexport const delay = (\n milliSeconds: number = 1000,\n signal?: AbortSignal\n): Promise<void> => {\n if (!isInteger(milliSeconds) || milliSeconds <= 0) {\n throw new TypeError(\n `First parameter (\\`milliSeconds\\`) must be of type \\`number\\` and value must be a \\`non-zero\\`, \\`non-NaN\\`, \\`non-negative\\`, and \\`integer-number\\`, but received: \\`${getPreciseType(\n milliSeconds\n )}\\`, with value: \\`${safeStableStringify(milliSeconds, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n if (isNull(signal) || (signal && !(signal instanceof AbortSignal))) {\n throw new TypeError(\n \"Second parameter (`signal`) must be an `instance of AbortSignal` if provided.\"\n );\n }\n\n return new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n cleanup();\n resolve();\n }, milliSeconds);\n\n const cleanup = () => {\n clearTimeout(timer);\n if (signal) signal.removeEventListener(\"abort\", onAbort);\n };\n\n const onAbort = () => {\n cleanup();\n reject(\n new AbortError(\n \"Function `delay` from `@rzl-zone/utils-js` was aborted.\",\n \"AbortError\"\n )\n );\n };\n\n if (signal) {\n if (signal.aborted) {\n onAbort();\n } else {\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n }\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiEA,IAAa,gBAAb,cACU,QAEV;CACE,AAAQ;CACR,AAAQ;CACR,AAAQ,UAAmD,EAAE;CAE7D,YACE,UAIA;EACA,IAAI;EACJ,IAAI;EAEJ,OAAO,SAAS,WAAW;GACzB,eAAe;GACf,cAAc;IACd;EAEF,UACG,MAAM;GACL,KAAK,SAAS;GACd,aAAa,EAAE;GACf,KAAK,QAAQ,SAAS,MAAM,EAAE,GAAG,OAAU,CAAC;MAE7C,MAAM;GACL,KAAK,SAAS;GACd,YAAY,EAAE;GACd,KAAK,QAAQ,SAAS,MAAM,EAAE,QAAW,EAAE,CAAC;IAE/C;EAED,OAAO,eAAe,MAAM,IAAI,OAAO,UAAU;;CAGnD,AAAS,KACP,aACA,YAC2C;EAC3C,OAAO,MAAM,KAAK,aAAa,WAAW;;CAM5C,AAAS,MACP,YACyC;EACzC,OAAO,MAAM,MAAM,WAAW;;;;;;;;;;;;;CAiBhC,OAAO,IAAgD;EACrD,IAAI,KAAK,WAAW,UAAa,KAAK,WAAW,QAC/C,GAAG,KAAK,QAAQ,KAAK,OAAO;OAE5B,KAAK,QAAQ,KAAK,GAAG;EAEvB,OAAO;;;;;;;;;;AClIX,IAAM,aAAN,cAAyB,MAAM;CAC7B,YACE,UAAkB,6BAClB,OAAe,cACf;EACA,MAAM,QAAQ;EACd,KAAK,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiChB,MAAa,SACX,eAAuB,KACvB,WACkB;CAClB,IAAI,CAACA,4BAAU,aAAa,IAAI,gBAAgB,GAC9C,MAAM,IAAI,UACR,0KAA0KC,uCACxK,aACD,CAAC,oBAAoBC,gDAAoB,cAAc,EACtD,eAAe,MAChB,CAAC,CAAC,KACJ;CAGH,IAAIC,+BAAO,OAAO,IAAK,UAAU,EAAE,kBAAkB,cACnD,MAAM,IAAI,UACR,gFACD;CAGH,OAAO,IAAI,SAAe,SAAS,WAAW;EAC5C,MAAM,QAAQ,iBAAiB;GAC7B,SAAS;GACT,SAAS;KACR,aAAa;EAEhB,MAAM,gBAAgB;GACpB,aAAa,MAAM;GACnB,IAAI,QAAQ,OAAO,oBAAoB,SAAS,QAAQ;;EAG1D,MAAM,gBAAgB;GACpB,SAAS;GACT,OACE,IAAI,WACF,2DACA,aACD,CACF;;EAGH,IAAI,QACF,IAAI,OAAO,SACT,SAAS;OAET,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,MAAM,CAAC;GAG7D"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ========================================================================
|
|
3
|
+
* @rzl-zone/utils-js
|
|
4
|
+
* ------------------------------------------------------------------------
|
|
5
|
+
* Version: `3.12.1-beta.1`
|
|
6
|
+
* Author: `Rizalvin Dwiky <rizalvindwiky@gmail.com>`
|
|
7
|
+
* Repository: `https://github.com/rzl-zone/rzl-zone/tree/main/packages/utils-js`
|
|
8
|
+
* ========================================================================
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { CustomPromiseType } from "@rzl-zone/ts-types-plus";
|
|
12
|
+
/** -------------------------------------------------------------
|
|
13
|
+
* * ***Utility Class: `CustomPromise`.***
|
|
14
|
+
* -------------------------------------------------------------
|
|
15
|
+
* **A strongly typed extension of the native {@link Promise | **`Promise`**}.**
|
|
16
|
+
* 1. **Behaves exactly like a normal Promise** for `then`/`catch`
|
|
17
|
+
* and `await` semantics.
|
|
18
|
+
* 2. **Stores the final resolution or rejection internally** so
|
|
19
|
+
* it can be retrieved by a custom `finish` handler.
|
|
20
|
+
* 3. **Adds a `finish` method** which runs once after settlement
|
|
21
|
+
* with access to both the fulfilled value *and* the rejection
|
|
22
|
+
* reason (only one will be defined).
|
|
23
|
+
* - **Key Differences from a Native `Promise`:**
|
|
24
|
+
* - Every call to `then`/`catch` returns **`CustomPromise`**
|
|
25
|
+
* again, so the `finish` method remains available on the
|
|
26
|
+
* entire chain.
|
|
27
|
+
* - `finish` provides a tuple-like callback:
|
|
28
|
+
* - `val` → defined when fulfilled.
|
|
29
|
+
* - `err` → defined when rejected.
|
|
30
|
+
* @template Success Type of the resolved value.
|
|
31
|
+
* @template Error Type of the rejection reason (default `unknown`).
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { CustomPromise, type CustomPromiseType } from "@rzl-zone/utils-js/promises";
|
|
35
|
+
*
|
|
36
|
+
* type User = { id: number; name: string };
|
|
37
|
+
* type ApiError = { message: string };
|
|
38
|
+
*
|
|
39
|
+
* function fetchUser(): CustomPromiseType<User, ApiError> {
|
|
40
|
+
* return new CustomPromise<User, ApiError>((resolve, reject) => {
|
|
41
|
+
* setTimeout(
|
|
42
|
+
* () =>
|
|
43
|
+
* void (Math.random() > 0.5
|
|
44
|
+
* ? resolve({ id: 1, name: "Alice" })
|
|
45
|
+
* : reject({ message: "Random failure" })),
|
|
46
|
+
* 500
|
|
47
|
+
* );
|
|
48
|
+
* });
|
|
49
|
+
* }
|
|
50
|
+
*
|
|
51
|
+
* fetchUser()
|
|
52
|
+
* .then(user => {
|
|
53
|
+
* console.log("SUCCESS:", user);
|
|
54
|
+
* return user;
|
|
55
|
+
* })
|
|
56
|
+
* .catch(err => {
|
|
57
|
+
* console.error("ERROR:", err);
|
|
58
|
+
* throw err;
|
|
59
|
+
* })
|
|
60
|
+
* .finish((val, err) => {
|
|
61
|
+
* // Runs once after settle, regardless of outcome
|
|
62
|
+
* console.log("FINISH:", { val, err });
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
* ---
|
|
66
|
+
* - **Implementation Notes:**
|
|
67
|
+
* - Uses `Object.setPrototypeOf` to preserve the prototype chain
|
|
68
|
+
* for environments targeting ES5 or when subclassing Promise.
|
|
69
|
+
* - Internal `_value` and `_error` are updated as soon as the
|
|
70
|
+
* executor resolves or rejects, guaranteeing `finish` receives
|
|
71
|
+
* the final state even when added after settlement.
|
|
72
|
+
*/
|
|
73
|
+
declare class CustomPromise<Success, Error = unknown> extends Promise<Success> implements CustomPromiseType<Success, Error> {
|
|
74
|
+
private _value?;
|
|
75
|
+
private _error?;
|
|
76
|
+
private _finish;
|
|
77
|
+
constructor(executor: (resolve: (v: Success) => void, reject: (e: Error) => void) => void);
|
|
78
|
+
override then<TResult1 = Success, TResult2 = never>(onfulfilled?: ((value: Success) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: Error) => TResult2 | PromiseLike<TResult2>) | null): CustomPromise<TResult1 | TResult2, Error>;
|
|
79
|
+
override catch<TResult = never>(onrejected?: ((reason: Error) => TResult | PromiseLike<TResult>) | null): CustomPromise<Success | TResult, Error>;
|
|
80
|
+
/**
|
|
81
|
+
* Registers a callback to be invoked **exactly once** when the
|
|
82
|
+
* promise settles, with access to both the resolved value and
|
|
83
|
+
* the rejection reason.
|
|
84
|
+
*
|
|
85
|
+
* If the promise is already settled when `finish` is called,
|
|
86
|
+
* the callback executes immediately on the same tick.
|
|
87
|
+
*
|
|
88
|
+
* @param cb Callback receiving the final `(value, error)`.
|
|
89
|
+
* @returns `this` for fluent chaining.
|
|
90
|
+
*/
|
|
91
|
+
finish(cb: (val?: Success, err?: Error) => void): this;
|
|
92
|
+
}
|
|
93
|
+
/** ------------------------------------------------------------
|
|
94
|
+
* * ***Utility: `delay`.***
|
|
95
|
+
* ------------------------------------------------------------
|
|
96
|
+
* **Creates a Promise-based delay that resolves after a given number
|
|
97
|
+
* of milliseconds, optionally supports cancellation with `AbortSignal`.**
|
|
98
|
+
* - **Behavior:**
|
|
99
|
+
* - Validates `milliSeconds` is a non-zero, non-negative integer.
|
|
100
|
+
* - Validates `signal` is an `AbortSignal` instance when provided.
|
|
101
|
+
* - Cleans up event listeners and timers properly.
|
|
102
|
+
* @param {number} [milliSeconds=1000]
|
|
103
|
+
* The duration of the delay in milliseconds, default is `1000`.
|
|
104
|
+
* @param {AbortSignal} [signal]
|
|
105
|
+
* An optional `AbortSignal` that can cancel the delay.
|
|
106
|
+
* @returns {Promise<void>}
|
|
107
|
+
* A promise that resolves after the specified delay or
|
|
108
|
+
* rejects with an `AbortError` if aborted.
|
|
109
|
+
* @throws **{@link TypeError | `TypeError`}** while validates `milliSeconds` and `signal`:
|
|
110
|
+
* - If `milliSeconds` **is not a valid** an `integer-number`, `NaN`, `negative-number`, or `≤ 0`.
|
|
111
|
+
* - If `signal` **is not a valid** an`AbortSignal`.
|
|
112
|
+
* @throws **{@link DOMException | `DOMException`}** if the delay is aborted using the signal, rejects with `AbortError`.
|
|
113
|
+
* @example
|
|
114
|
+
* // Waits for 2 seconds
|
|
115
|
+
* await delay(2000);
|
|
116
|
+
*
|
|
117
|
+
* // Delay with AbortSignal
|
|
118
|
+
* const controller = new AbortController();
|
|
119
|
+
* delay(5000, controller.signal).catch(err => console.log(err.name)); // "AbortError"
|
|
120
|
+
* controller.abort();
|
|
121
|
+
*/
|
|
122
|
+
declare const delay: (milliSeconds?: number, signal?: AbortSignal) => Promise<void>;
|
|
123
|
+
export { CustomPromise, type CustomPromiseType, delay };
|
package/dist/promises/index.d.ts
CHANGED
|
@@ -1,126 +1,123 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import { CustomPromiseType } from '@rzl-zone/ts-types-plus';
|
|
11
|
-
export { CustomPromiseType } from '@rzl-zone/ts-types-plus';
|
|
2
|
+
* ========================================================================
|
|
3
|
+
* @rzl-zone/utils-js
|
|
4
|
+
* ------------------------------------------------------------------------
|
|
5
|
+
* Version: `3.12.1-beta.1`
|
|
6
|
+
* Author: `Rizalvin Dwiky <rizalvindwiky@gmail.com>`
|
|
7
|
+
* Repository: `https://github.com/rzl-zone/rzl-zone/tree/main/packages/utils-js`
|
|
8
|
+
* ========================================================================
|
|
9
|
+
*/
|
|
12
10
|
|
|
11
|
+
import { CustomPromiseType } from "@rzl-zone/ts-types-plus";
|
|
13
12
|
/** -------------------------------------------------------------
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
13
|
+
* * ***Utility Class: `CustomPromise`.***
|
|
14
|
+
* -------------------------------------------------------------
|
|
15
|
+
* **A strongly typed extension of the native {@link Promise | **`Promise`**}.**
|
|
16
|
+
* 1. **Behaves exactly like a normal Promise** for `then`/`catch`
|
|
17
|
+
* and `await` semantics.
|
|
18
|
+
* 2. **Stores the final resolution or rejection internally** so
|
|
19
|
+
* it can be retrieved by a custom `finish` handler.
|
|
20
|
+
* 3. **Adds a `finish` method** which runs once after settlement
|
|
21
|
+
* with access to both the fulfilled value *and* the rejection
|
|
22
|
+
* reason (only one will be defined).
|
|
23
|
+
* - **Key Differences from a Native `Promise`:**
|
|
24
|
+
* - Every call to `then`/`catch` returns **`CustomPromise`**
|
|
25
|
+
* again, so the `finish` method remains available on the
|
|
26
|
+
* entire chain.
|
|
27
|
+
* - `finish` provides a tuple-like callback:
|
|
28
|
+
* - `val` → defined when fulfilled.
|
|
29
|
+
* - `err` → defined when rejected.
|
|
30
|
+
* @template Success Type of the resolved value.
|
|
31
|
+
* @template Error Type of the rejection reason (default `unknown`).
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { CustomPromise, type CustomPromiseType } from "@rzl-zone/utils-js/promises";
|
|
35
|
+
*
|
|
36
|
+
* type User = { id: number; name: string };
|
|
37
|
+
* type ApiError = { message: string };
|
|
38
|
+
*
|
|
39
|
+
* function fetchUser(): CustomPromiseType<User, ApiError> {
|
|
40
|
+
* return new CustomPromise<User, ApiError>((resolve, reject) => {
|
|
41
|
+
* setTimeout(
|
|
42
|
+
* () =>
|
|
43
|
+
* void (Math.random() > 0.5
|
|
44
|
+
* ? resolve({ id: 1, name: "Alice" })
|
|
45
|
+
* : reject({ message: "Random failure" })),
|
|
46
|
+
* 500
|
|
47
|
+
* );
|
|
48
|
+
* });
|
|
49
|
+
* }
|
|
50
|
+
*
|
|
51
|
+
* fetchUser()
|
|
52
|
+
* .then(user => {
|
|
53
|
+
* console.log("SUCCESS:", user);
|
|
54
|
+
* return user;
|
|
55
|
+
* })
|
|
56
|
+
* .catch(err => {
|
|
57
|
+
* console.error("ERROR:", err);
|
|
58
|
+
* throw err;
|
|
59
|
+
* })
|
|
60
|
+
* .finish((val, err) => {
|
|
61
|
+
* // Runs once after settle, regardless of outcome
|
|
62
|
+
* console.log("FINISH:", { val, err });
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
* ---
|
|
66
|
+
* - **Implementation Notes:**
|
|
67
|
+
* - Uses `Object.setPrototypeOf` to preserve the prototype chain
|
|
68
|
+
* for environments targeting ES5 or when subclassing Promise.
|
|
69
|
+
* - Internal `_value` and `_error` are updated as soon as the
|
|
70
|
+
* executor resolves or rejects, guaranteeing `finish` receives
|
|
71
|
+
* the final state even when added after settlement.
|
|
72
|
+
*/
|
|
74
73
|
declare class CustomPromise<Success, Error = unknown> extends Promise<Success> implements CustomPromiseType<Success, Error> {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
74
|
+
private _value?;
|
|
75
|
+
private _error?;
|
|
76
|
+
private _finish;
|
|
77
|
+
constructor(executor: (resolve: (v: Success) => void, reject: (e: Error) => void) => void);
|
|
78
|
+
override then<TResult1 = Success, TResult2 = never>(onfulfilled?: ((value: Success) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: Error) => TResult2 | PromiseLike<TResult2>) | null): CustomPromise<TResult1 | TResult2, Error>;
|
|
79
|
+
override catch<TResult = never>(onrejected?: ((reason: Error) => TResult | PromiseLike<TResult>) | null): CustomPromise<Success | TResult, Error>;
|
|
80
|
+
/**
|
|
81
|
+
* Registers a callback to be invoked **exactly once** when the
|
|
82
|
+
* promise settles, with access to both the resolved value and
|
|
83
|
+
* the rejection reason.
|
|
84
|
+
*
|
|
85
|
+
* If the promise is already settled when `finish` is called,
|
|
86
|
+
* the callback executes immediately on the same tick.
|
|
87
|
+
*
|
|
88
|
+
* @param cb Callback receiving the final `(value, error)`.
|
|
89
|
+
* @returns `this` for fluent chaining.
|
|
90
|
+
*/
|
|
91
|
+
finish(cb: (val?: Success, err?: Error) => void): this;
|
|
93
92
|
}
|
|
94
|
-
|
|
95
93
|
/** ------------------------------------------------------------
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
94
|
+
* * ***Utility: `delay`.***
|
|
95
|
+
* ------------------------------------------------------------
|
|
96
|
+
* **Creates a Promise-based delay that resolves after a given number
|
|
97
|
+
* of milliseconds, optionally supports cancellation with `AbortSignal`.**
|
|
98
|
+
* - **Behavior:**
|
|
99
|
+
* - Validates `milliSeconds` is a non-zero, non-negative integer.
|
|
100
|
+
* - Validates `signal` is an `AbortSignal` instance when provided.
|
|
101
|
+
* - Cleans up event listeners and timers properly.
|
|
102
|
+
* @param {number} [milliSeconds=1000]
|
|
103
|
+
* The duration of the delay in milliseconds, default is `1000`.
|
|
104
|
+
* @param {AbortSignal} [signal]
|
|
105
|
+
* An optional `AbortSignal` that can cancel the delay.
|
|
106
|
+
* @returns {Promise<void>}
|
|
107
|
+
* A promise that resolves after the specified delay or
|
|
108
|
+
* rejects with an `AbortError` if aborted.
|
|
109
|
+
* @throws **{@link TypeError | `TypeError`}** while validates `milliSeconds` and `signal`:
|
|
110
|
+
* - If `milliSeconds` **is not a valid** an `integer-number`, `NaN`, `negative-number`, or `≤ 0`.
|
|
111
|
+
* - If `signal` **is not a valid** an`AbortSignal`.
|
|
112
|
+
* @throws **{@link DOMException | `DOMException`}** if the delay is aborted using the signal, rejects with `AbortError`.
|
|
113
|
+
* @example
|
|
114
|
+
* // Waits for 2 seconds
|
|
115
|
+
* await delay(2000);
|
|
116
|
+
*
|
|
117
|
+
* // Delay with AbortSignal
|
|
118
|
+
* const controller = new AbortController();
|
|
119
|
+
* delay(5000, controller.signal).catch(err => console.log(err.name)); // "AbortError"
|
|
120
|
+
* controller.abort();
|
|
121
|
+
*/
|
|
124
122
|
declare const delay: (milliSeconds?: number, signal?: AbortSignal) => Promise<void>;
|
|
125
|
-
|
|
126
|
-
export { CustomPromise, delay };
|
|
123
|
+
export { CustomPromise, type CustomPromiseType, delay };
|
package/dist/promises/index.js
CHANGED
|
@@ -1,14 +1,74 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
|
|
14
|
-
|
|
2
|
+
* ========================================================================
|
|
3
|
+
* @rzl-zone/utils-js
|
|
4
|
+
* ------------------------------------------------------------------------
|
|
5
|
+
* Version: `3.12.1-beta.1`
|
|
6
|
+
* Author: `Rizalvin Dwiky <rizalvindwiky@gmail.com>`
|
|
7
|
+
* Repository: `https://github.com/rzl-zone/rzl-zone/tree/main/packages/utils-js`
|
|
8
|
+
* ========================================================================
|
|
9
|
+
*/
|
|
10
|
+
import { E as isNull, r as getPreciseType } from "../assertIsBoolean-DR1SaXPD.js";
|
|
11
|
+
import { t as safeStableStringify } from "../safeStableStringify-CXOZ9Ub8.js";
|
|
12
|
+
import { t as isInteger } from "../isInteger-naMbJsxJ.js";
|
|
13
|
+
var CustomPromise = class extends Promise {
|
|
14
|
+
_value;
|
|
15
|
+
_error;
|
|
16
|
+
_finish = [];
|
|
17
|
+
constructor(executor) {
|
|
18
|
+
let resolveOuter;
|
|
19
|
+
let rejectOuter;
|
|
20
|
+
super((resolve, reject) => {
|
|
21
|
+
resolveOuter = resolve;
|
|
22
|
+
rejectOuter = reject;
|
|
23
|
+
});
|
|
24
|
+
executor((v) => {
|
|
25
|
+
this._value = v;
|
|
26
|
+
resolveOuter(v);
|
|
27
|
+
this._finish.forEach((f) => f(v, void 0));
|
|
28
|
+
}, (e) => {
|
|
29
|
+
this._error = e;
|
|
30
|
+
rejectOuter(e);
|
|
31
|
+
this._finish.forEach((f) => f(void 0, e));
|
|
32
|
+
});
|
|
33
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
34
|
+
}
|
|
35
|
+
then(onfulfilled, onrejected) {
|
|
36
|
+
return super.then(onfulfilled, onrejected);
|
|
37
|
+
}
|
|
38
|
+
catch(onrejected) {
|
|
39
|
+
return super.catch(onrejected);
|
|
40
|
+
}
|
|
41
|
+
finish(cb) {
|
|
42
|
+
if (this._value !== void 0 || this._error !== void 0) cb(this._value, this._error);
|
|
43
|
+
else this._finish.push(cb);
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
var AbortError = class extends Error {
|
|
48
|
+
constructor(message = "The operation was aborted", name = "AbortError") {
|
|
49
|
+
super(message);
|
|
50
|
+
this.name = name;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const delay = (milliSeconds = 1e3, signal) => {
|
|
54
|
+
if (!isInteger(milliSeconds) || milliSeconds <= 0) throw new TypeError(`First parameter (\`milliSeconds\`) must be of type \`number\` and value must be a \`non-zero\`, \`non-NaN\`, \`non-negative\`, and \`integer-number\`, but received: \`${getPreciseType(milliSeconds)}\`, with value: \`${safeStableStringify(milliSeconds, { keepUndefined: true })}\`.`);
|
|
55
|
+
if (isNull(signal) || signal && !(signal instanceof AbortSignal)) throw new TypeError("Second parameter (`signal`) must be an `instance of AbortSignal` if provided.");
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
const timer = setTimeout(() => {
|
|
58
|
+
cleanup();
|
|
59
|
+
resolve();
|
|
60
|
+
}, milliSeconds);
|
|
61
|
+
const cleanup = () => {
|
|
62
|
+
clearTimeout(timer);
|
|
63
|
+
if (signal) signal.removeEventListener("abort", onAbort);
|
|
64
|
+
};
|
|
65
|
+
const onAbort = () => {
|
|
66
|
+
cleanup();
|
|
67
|
+
reject(new AbortError("Function `delay` from `@rzl-zone/utils-js` was aborted.", "AbortError"));
|
|
68
|
+
};
|
|
69
|
+
if (signal) if (signal.aborted) onAbort();
|
|
70
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
export { CustomPromise, delay };
|
|
74
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/promises/CustomPromise.ts","../../src/promises/delay.ts"],"sourcesContent":["import type { CustomPromiseType } from \"@rzl-zone/ts-types-plus\";\n\nexport type { CustomPromiseType };\n\n/** -------------------------------------------------------------\n * * ***Utility Class: `CustomPromise`.***\n * -------------------------------------------------------------\n * **A strongly typed extension of the native {@link Promise | **`Promise`**}.**\n * 1. **Behaves exactly like a normal Promise** for `then`/`catch`\n * and `await` semantics.\n * 2. **Stores the final resolution or rejection internally** so\n * it can be retrieved by a custom `finish` handler.\n * 3. **Adds a `finish` method** which runs once after settlement\n * with access to both the fulfilled value *and* the rejection\n * reason (only one will be defined).\n * - **Key Differences from a Native `Promise`:**\n * - Every call to `then`/`catch` returns **`CustomPromise`**\n * again, so the `finish` method remains available on the\n * entire chain.\n * - `finish` provides a tuple-like callback:\n * - `val` → defined when fulfilled.\n * - `err` → defined when rejected.\n * @template Success Type of the resolved value.\n * @template Error Type of the rejection reason (default `unknown`).\n * @example\n * ```ts\n * import { CustomPromise, type CustomPromiseType } from \"@rzl-zone/utils-js/promises\";\n *\n * type User = { id: number; name: string };\n * type ApiError = { message: string };\n *\n * function fetchUser(): CustomPromiseType<User, ApiError> {\n * return new CustomPromise<User, ApiError>((resolve, reject) => {\n * setTimeout(\n * () =>\n * void (Math.random() > 0.5\n * ? resolve({ id: 1, name: \"Alice\" })\n * : reject({ message: \"Random failure\" })),\n * 500\n * );\n * });\n * }\n *\n * fetchUser()\n * .then(user => {\n * console.log(\"SUCCESS:\", user);\n * return user;\n * })\n * .catch(err => {\n * console.error(\"ERROR:\", err);\n * throw err;\n * })\n * .finish((val, err) => {\n * // Runs once after settle, regardless of outcome\n * console.log(\"FINISH:\", { val, err });\n * });\n * ```\n * ---\n * - **Implementation Notes:**\n * - Uses `Object.setPrototypeOf` to preserve the prototype chain\n * for environments targeting ES5 or when subclassing Promise.\n * - Internal `_value` and `_error` are updated as soon as the\n * executor resolves or rejects, guaranteeing `finish` receives\n * the final state even when added after settlement.\n */\nexport class CustomPromise<Success, Error = unknown>\n extends Promise<Success>\n implements CustomPromiseType<Success, Error>\n{\n private _value?: Success;\n private _error?: Error;\n private _finish: Array<(v?: Success, e?: Error) => void> = [];\n\n constructor(\n executor: (\n resolve: (v: Success) => void,\n reject: (e: Error) => void\n ) => void\n ) {\n let resolveOuter!: (v: Success) => void;\n let rejectOuter!: (e: Error) => void;\n\n super((resolve, reject) => {\n resolveOuter = resolve;\n rejectOuter = reject;\n });\n\n executor(\n (v) => {\n this._value = v;\n resolveOuter(v);\n this._finish.forEach((f) => f(v, undefined));\n },\n (e) => {\n this._error = e;\n rejectOuter(e);\n this._finish.forEach((f) => f(undefined, e));\n }\n );\n\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n override then<TResult1 = Success, TResult2 = never>(\n onfulfilled?: ((value: Success) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: Error) => TResult2 | PromiseLike<TResult2>) | null\n ): CustomPromise<TResult1 | TResult2, Error> {\n return super.then(onfulfilled, onrejected) as unknown as CustomPromise<\n TResult1 | TResult2,\n Error\n >;\n }\n\n override catch<TResult = never>(\n onrejected?: ((reason: Error) => TResult | PromiseLike<TResult>) | null\n ): CustomPromise<Success | TResult, Error> {\n return super.catch(onrejected) as unknown as CustomPromise<\n Success | TResult,\n Error\n >;\n }\n\n /**\n * Registers a callback to be invoked **exactly once** when the\n * promise settles, with access to both the resolved value and\n * the rejection reason.\n *\n * If the promise is already settled when `finish` is called,\n * the callback executes immediately on the same tick.\n *\n * @param cb Callback receiving the final `(value, error)`.\n * @returns `this` for fluent chaining.\n */\n finish(cb: (val?: Success, err?: Error) => void): this {\n if (this._value !== undefined || this._error !== undefined) {\n cb(this._value, this._error);\n } else {\n this._finish.push(cb);\n }\n return this;\n }\n}\n","import { isNull } from \"@/predicates/is/isNull\";\nimport { isInteger } from \"@/predicates/is/isInteger\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\n\n/** -------------------------------------------------------------------\n * * ***Custom `AbortError` for cross-runtime delay cancellation.***\n * -------------------------------------------------------------------\n */\nclass AbortError extends Error {\n constructor(\n message: string = \"The operation was aborted\",\n name: string = \"AbortError\"\n ) {\n super(message);\n this.name = name;\n }\n}\n\n/** ------------------------------------------------------------\n * * ***Utility: `delay`.***\n * ------------------------------------------------------------\n * **Creates a Promise-based delay that resolves after a given number\n * of milliseconds, optionally supports cancellation with `AbortSignal`.**\n * - **Behavior:**\n * - Validates `milliSeconds` is a non-zero, non-negative integer.\n * - Validates `signal` is an `AbortSignal` instance when provided.\n * - Cleans up event listeners and timers properly.\n * @param {number} [milliSeconds=1000]\n * The duration of the delay in milliseconds, default is `1000`.\n * @param {AbortSignal} [signal]\n * An optional `AbortSignal` that can cancel the delay.\n * @returns {Promise<void>}\n * A promise that resolves after the specified delay or\n * rejects with an `AbortError` if aborted.\n * @throws **{@link TypeError | `TypeError`}** while validates `milliSeconds` and `signal`:\n * - If `milliSeconds` **is not a valid** an `integer-number`, `NaN`, `negative-number`, or `≤ 0`.\n * - If `signal` **is not a valid** an`AbortSignal`.\n * @throws **{@link DOMException | `DOMException`}** if the delay is aborted using the signal, rejects with `AbortError`.\n * @example\n * // Waits for 2 seconds\n * await delay(2000);\n *\n * // Delay with AbortSignal\n * const controller = new AbortController();\n * delay(5000, controller.signal).catch(err => console.log(err.name)); // \"AbortError\"\n * controller.abort();\n */\nexport const delay = (\n milliSeconds: number = 1000,\n signal?: AbortSignal\n): Promise<void> => {\n if (!isInteger(milliSeconds) || milliSeconds <= 0) {\n throw new TypeError(\n `First parameter (\\`milliSeconds\\`) must be of type \\`number\\` and value must be a \\`non-zero\\`, \\`non-NaN\\`, \\`non-negative\\`, and \\`integer-number\\`, but received: \\`${getPreciseType(\n milliSeconds\n )}\\`, with value: \\`${safeStableStringify(milliSeconds, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n if (isNull(signal) || (signal && !(signal instanceof AbortSignal))) {\n throw new TypeError(\n \"Second parameter (`signal`) must be an `instance of AbortSignal` if provided.\"\n );\n }\n\n return new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n cleanup();\n resolve();\n }, milliSeconds);\n\n const cleanup = () => {\n clearTimeout(timer);\n if (signal) signal.removeEventListener(\"abort\", onAbort);\n };\n\n const onAbort = () => {\n cleanup();\n reject(\n new AbortError(\n \"Function `delay` from `@rzl-zone/utils-js` was aborted.\",\n \"AbortError\"\n )\n );\n };\n\n if (signal) {\n if (signal.aborted) {\n onAbort();\n } else {\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n }\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiEA,IAAa,gBAAb,cACU,QAEV;CACE,AAAQ;CACR,AAAQ;CACR,AAAQ,UAAmD,EAAE;CAE7D,YACE,UAIA;EACA,IAAI;EACJ,IAAI;EAEJ,OAAO,SAAS,WAAW;GACzB,eAAe;GACf,cAAc;IACd;EAEF,UACG,MAAM;GACL,KAAK,SAAS;GACd,aAAa,EAAE;GACf,KAAK,QAAQ,SAAS,MAAM,EAAE,GAAG,OAAU,CAAC;MAE7C,MAAM;GACL,KAAK,SAAS;GACd,YAAY,EAAE;GACd,KAAK,QAAQ,SAAS,MAAM,EAAE,QAAW,EAAE,CAAC;IAE/C;EAED,OAAO,eAAe,MAAM,IAAI,OAAO,UAAU;;CAGnD,AAAS,KACP,aACA,YAC2C;EAC3C,OAAO,MAAM,KAAK,aAAa,WAAW;;CAM5C,AAAS,MACP,YACyC;EACzC,OAAO,MAAM,MAAM,WAAW;;;;;;;;;;;;;CAiBhC,OAAO,IAAgD;EACrD,IAAI,KAAK,WAAW,UAAa,KAAK,WAAW,QAC/C,GAAG,KAAK,QAAQ,KAAK,OAAO;OAE5B,KAAK,QAAQ,KAAK,GAAG;EAEvB,OAAO;;;;;;;;;;AClIX,IAAM,aAAN,cAAyB,MAAM;CAC7B,YACE,UAAkB,6BAClB,OAAe,cACf;EACA,MAAM,QAAQ;EACd,KAAK,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiChB,MAAa,SACX,eAAuB,KACvB,WACkB;CAClB,IAAI,CAAC,UAAU,aAAa,IAAI,gBAAgB,GAC9C,MAAM,IAAI,UACR,0KAA0K,eACxK,aACD,CAAC,oBAAoB,oBAAoB,cAAc,EACtD,eAAe,MAChB,CAAC,CAAC,KACJ;CAGH,IAAI,OAAO,OAAO,IAAK,UAAU,EAAE,kBAAkB,cACnD,MAAM,IAAI,UACR,gFACD;CAGH,OAAO,IAAI,SAAe,SAAS,WAAW;EAC5C,MAAM,QAAQ,iBAAiB;GAC7B,SAAS;GACT,SAAS;KACR,aAAa;EAEhB,MAAM,gBAAgB;GACpB,aAAa,MAAM;GACnB,IAAI,QAAQ,OAAO,oBAAoB,SAAS,QAAQ;;EAG1D,MAAM,gBAAgB;GACpB,SAAS;GACT,OACE,IAAI,WACF,2DACA,aACD,CACF;;EAGH,IAAI,QACF,IAAI,OAAO,SACT,SAAS;OAET,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,MAAM,CAAC;GAG7D"}
|